java SwingWorker从doInBackground()启动runnables和如何通知事件调度线程

java SwingWorker从doInBackground()启动runnables和如何通知事件调度线程,java,swing,callback,swingworker,event-dispatch-thread,Java,Swing,Callback,Swingworker,Event Dispatch Thread,只需了解SwingWorker并提出一个问题 (我已搜索此问题的答案,但未具体说明此设置) 我正在创建一个小型服务器,该服务器最多只能同时连接2-3个连接。 我使用的是具有内部类的Jframe,SwingWorker 在SwingWorkerdoInBackground()中,我有: while(true) { Socket client_socket = listen_socket.accept(); Connection con = new Connection(client_soc

只需了解
SwingWorker
并提出一个问题
(我已搜索此问题的答案,但未具体说明此设置)

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

在SwingWorker
doInBackground()
中,我有:

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);
 }
while(true){
Socket client_Socket=侦听_Socket.accept();
Connection con=新连接(客户端_套接字,“名称”);
未来=提交(con,con);
任务。添加(未来);
}
连接
是一个
可运行的
,在
SwingWorker
中声明为子类

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

最好的做法是:

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

2-对所有新连接使用
SwingWorker
而不是
runnables
,并使用
EventQueue.invokeLater..
调用服务器
SwingWorker
中的方法调用
Jframe
中的方法

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


4-让每个可运行程序对
Jframe
和do
EventQueue.invokeLater..

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

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

真的就这么简单

编辑:
让它更清楚。假设您的
连接
类扩展了
SwingWorker
,则不需要实现
可运行
,也不需要显式提供线程池来运行工作线程。只需将
run()
方法的内容放入
doInBackground()
中即可

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

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

您似乎正在向主循环中的
ExecutorService
提交。有没有具体的原因(请注意,
SwingWorker
为工作线程管理自己的内部
ThreadPoolExecutor
)。是为了限制并发客户端的数量吗?如果是这样,还有其他方法可以实现这一点。

我尝试创建一个SwingWorker示例,该示例生成后台工作线程,其结果通过固定池ExecutorService和CompletionService发布。关于在一个线程中创建工作线程,然后在另一个线程(SwingWorker后台线程)中调用get来实现其未来的线程安全性,我仍然有一些问题

例如:

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();
         }
      });
   }
}
导入java.awt.BorderLayout;
导入java.awt.event.ActionEvent;
导入java.util.List;
导入java.util.concurrent.Callable;
导入java.util.concurrent.CompletionService;
导入java.util.concurrent.ExecutionException;
导入java.util.concurrent.ExecutionCompletionService;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.Future;
导入javax.swing.*;
@抑制警告(“串行”)
公共类TestSwingWorker扩展了JPanel{
公共静态最终整数池大小=4;
私有JTextArea tArea=新JTextArea(10,30);
私人JButton doItBtn;
公共测试SwingWorker(){
doItBtn=newjbutton(newabstractaction(“doit!”){
已执行的公共无效行动(行动事件ae){
swingWorkerRunning(正确);
MySwingWorker mySW=新的MySwingWorker();
mySW.execute();
附加(“SwingWorker启动\n”);
}
});
JPanel btnPanel=新的JPanel();
btnPanel.add(doItBtn);
tArea.setEditable(false);
可聚焦的跗骨(假);
setLayout(新的BorderLayout());
添加(新的JScrollPane(tArea),BorderLayout.CENTER);
添加(btnPanel,BorderLayout.SOUTH);
}
私有类MyWingWorker扩展SwingWorker{
@凌驾
受保护的字符串doInBackground()引发异常{
ExecutorService Executors=Executors.newFixedThreadPool(池大小);
final CompletionService CompletionService=新的ExecutionCompletionService(
行政服务);
新线程(newrunnable()){
@凌驾
公开募捐{
对于(int i=0;i