2011-11-24 59 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(); 
     } 
     }); 
    } 
} 

更正最歡迎!