2011-11-24 61 views
4

只是learnd的SwingWorker并有一个问题
(我有搜索答案,这一点,但非专门解决这个设置)的Java SwingWorker类从doInBackground()和HOWTO推出可运行通知事件调度线程

林创建小型服务器,只有最多同时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); 
} 

Connectionrunnable和声明为SwingWorker一个子类。

runnable完成之前,它在SQL中写入一个条目。
那么如何才能在它死亡之前运行发送一个单挑到Jframe事件调度线程。
Jframe将检查新条目的SQL并将其显示给用户。

什么是最好的事:

1 - 创建一个接口女巫所有可运行可以发送邮件到Jframe事件调度线程。

2 - 使用SwingWorker insted的的runnables所有新连接,并具有Done()呼叫使用服务器SwingWorker调用方法Jframe方法EventQueue.invokeLater..

3 - 或使用一个PropertyChangeListener(不知何故没有确定)

4 - 让每个可运行参数的参考号为Jframe,并且做EventQueue.invokeLater..

回答

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。是否有特定原因(请注意,SwingWorker管理自己的内部工作线程ThreadPoolExecutor)。是否限制并发客户端的数量?如果有,还有其他方法可以实现这一点。

+0

我的服务器SwingWorker正在使用它的'done()',当服务器关闭。我从'doInBackground()'启动的所有'runnables'怎么样,他们没有'done()'机制 – Erik

+1

我认为他已经知道使用SwingWorker。他的问题超出了SwingWorker使用的基础。 –

+1

@Erik:他们是可运行的还是未来?如果是后者,那么他们确实有完善的方法,特别是如果FutureTask或类似的东西。 –

1

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

+0

可以工作。父母在我的情况是一个'SwingWorker',它已经阻止'doInBackground()listen_socket.accept()'。可以在父节点中启动一个监听线程,持有阻塞队列易失性列表,并使用EventQueue.invokeLater将消息发布到'Jframe'。我没有专家,这感觉有点矫枉过正 – Erik

+0

是的,我个人使用这个生产者/消费者在一个大型的分布式系统,并没有看到任何问题,迄今为止 – GETah

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(); 
     } 
     }); 
    } 
} 

更正最欢迎!