4

刚学会SwingWorker并有一个问题
(我已经搜索了这个问题的答案,但没有专门解决这个设置)

我正在创建一个小型服务器,它最多只能同时连接 2-3 个连接。
我正在使用Jframe具有内部类的SwingWorker

在 SwingWorkerdoInBackground()我有:

while(true) {
  Socket client_socket = listen_socket.accept();
  Connection con = new Connection(client_socket, "name");
  Future<Connection> future = es.submit(con , con ); 
  tasks.add(future);
 }

Connection是 arunnable并声明为 中的子类SwingWorker

runnable完成之前,它会在 SQL 中写入一个条目。
那么这个runnable如何在它死之前向Jframe事件调度线程发送一个提示。
并且Jframe将检查新条目的 SQL 并将其显示给用户。

最好做什么:

1 - 创建一个接口,所有可运行的都可以向Jframe事件调度线程发送消息。

2 -对所有新连接使用SwingWorkerinsted并在服务器中调用一个方法,该方法在使用中调用方法runnablesDone()SwingWorkerJframeEventQueue.invokeLater..

3 - 或使用 PropertyChangeListener (不知何故不确定)

4 - 让每个 runnables 都有 s ref to Jframeand doEventQueue.invokeLater..

4

3 回答 3

1

我会选择以下内容:在将传递给工作线程的父线程中有一个线程安全的阻塞队列或列表。任务完成后,工作线程会将包含结果条目 ID 的消息发布到此阻塞队列中。父线程将阻塞队列等待子线程的结果。每当队列中有一个元素时,父线程将获取它并从数据库中获取该数据并将其显示给用户。

于 2011-11-24T14:05:16.113 回答
1

SwingWorker文档很清楚。您应该子类SwingWorker化并在方法中执行长任务doInBackground()done()您应该在方法中更新 UI 。

真的就这么简单。

编辑:
使其更清晰。假设您的Connection类扩展SwingWorker不需要实现Runnable,并且您不需要显式提供线程池来运行工作人员。只需将run()方法的内容放入doInBackground().

现在你的主循环看起来像这样;

while (true) {
  Socket client_socket = listen_socket.accept();
  Connection con = new Connection(client_socket, "name");
  con.execute();
}

你似乎ExecutorService在你的主循环中提交。这是否有特定的原因(请注意, aSwingWorker管理自己ThreadPoolExecutor的工作线程内部)。是限制并发客户端的数量吗?如果是这样,还有其他方法可以做到这一点。

于 2011-11-24T14:08:49.560 回答
1

我尝试创建一个生成后台工作线程的 SwingWorker 示例,其结果通过固定池 ExecutorService 和 CompletionService 发布。我仍然对在一个线程内创建工作线程的线程安全性有一些疑问,然后在另一个线程(SwingWorker 后台线程)内调用他们的未来。

例如:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.swing.*;

@SuppressWarnings("serial")
public class TestSwingWorker extends JPanel {
   public static final int POOL_SIZE = 4;
   private JTextArea tArea = new JTextArea(10, 30);
   private JButton doItBtn;

   public TestSwingWorker() {
      doItBtn = new JButton(new AbstractAction("Do It!") {
         public void actionPerformed(ActionEvent ae) {
            swingWorkerRunning(true);
            MySwingWorker mySW = new MySwingWorker();
            mySW.execute();
            tArea.append("SwingWorker started\n");
         }
      });
      JPanel btnPanel = new JPanel();
      btnPanel.add(doItBtn);
      tArea.setEditable(false);
      tArea.setFocusable(false);

      setLayout(new BorderLayout());
      add(new JScrollPane(tArea), BorderLayout.CENTER);
      add(btnPanel, BorderLayout.SOUTH);
   }

   private class MySwingWorker extends SwingWorker<String, String> {
      @Override
      protected String doInBackground() throws Exception {
         ExecutorService execService = Executors.newFixedThreadPool(POOL_SIZE);
         final CompletionService<String> completionService = new ExecutorCompletionService<String>(
               execService);
         new Thread(new Runnable() {

            @Override
            public void run() {
               for (int i = 0; i < POOL_SIZE; i++) {
                  final int index = i;
                  completionService.submit(new Callable<String>() {
                     public String call() throws Exception {
                        Thread.sleep(2000 * index + 500);
                        return "Callable " + index + " complete";
                     }
                  });
                  try {
                     Thread.sleep(1000);
                  } catch (InterruptedException e) {
                  }
               }
            }
         }).start();

         for (int i = 0; i < POOL_SIZE; i++) {
            Future<String> f = completionService.take();
            publish(f.get());
         }

         return "Do in background done";
      }

      @Override
      protected void process(List<String> chunks) {
         for (String chunk : chunks) {
            tArea.append(chunk + "\n");
         }
      }

      @Override
      protected void done() {
         try {
            tArea.append(get() + "\n");
         } catch (InterruptedException e) {
            e.printStackTrace();
         } catch (ExecutionException e) {
            e.printStackTrace();
         } finally {
            swingWorkerRunning(false);
         }
      }
   }

   public void swingWorkerRunning(boolean running) {
      doItBtn.setEnabled(!running);
   }

   private static void createAndShowGui() {
      TestSwingWorker mainPanel = new TestSwingWorker();

      JFrame frame = new JFrame("TestSwingWorker");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

欢迎指正!

于 2011-11-24T17:43:24.303 回答