2011-03-01 84 views
11

我正在爲控制檯應用程序實現GUI,並且需要在指定的時間間隔內執行一些操作(例如,解析XML文件)。我決定和SwingWorker一起使用javax.swing.Timer,以確保這些操作不會使我的應用程序無響應。爲什麼我的SwingWorker線程即使執行完畢也能繼續運行?

我已實施的計時器是這樣的:

public class DataUpdateTimer extends Timer { 

    private String dataFlowControllerXML = null; 
    private DataUpdateWorker dataUpdateWorker = null; 

    public class DataUpdateWorker extends SwingWorker { 

     private String dataFlowControllerXML = null; 

     DataUpdateWorker(String dataFlowControllerXML) { 
      super(); 
      this.dataFlowControllerXML = dataFlowControllerXML; 
     } 

     @Override 
     protected Boolean doInBackground() throws Exception { 

      Thread.sleep(300); 
      return Boolean.TRUE; 
     } 

    } 

    public class DataUpdateIntervalListener implements ActionListener { 

     public void actionPerformed(ActionEvent e) { 
      DataUpdateTimer timer = (DataUpdateTimer)e.getSource(); 
      DataUpdateWorker dataUpdateWorker = timer.getDataUpdateWorker(); 

      if (dataUpdateWorker != null) 
       if (dataUpdateWorker.isDone()) { 
        Boolean updateResult = Boolean.FALSE; 
        try { 
         updateResult = (Boolean)dataUpdateWorker.get(); 
        } catch (InterruptedException ex) { 

        } catch (ExecutionException ex) { 

        } 

        dataUpdateWorker = null; 
       } 

      // Creating new worker thread here 
      if (dataUpdateWorker == null) { 
       timer.dataUpdateWorker = new DataUpdateWorker(timer.dataFlowControllerXML); 

       // Starting a new worker thread for parsing Data Flow Controller's XML 
       timer.dataUpdateWorker.execute(); 
       return; 
      } 
     } 
    } 

    DataUpdateTimer(Integer dataUpdateInterval, String dataFlowControllerXML) { 

     super(dataUpdateInterval.intValue(), null); 
     this.dataFlowControllerXML = dataFlowControllerXML; 
     addActionListener(new DataUpdateIntervalListener()); 
    } 

    @Override 
    public void stop() { 
     super.stop(); 
     if (dataUpdateWorker != null) { 
      if (!dataUpdateWorker.isDone() || !dataUpdateWorker.isCancelled()) 
       dataUpdateWorker.cancel(true); 
     } 
    } 
} 

...並且按如下方式使用它:

new DataUpdateTimer(1000, dataFlowControllerXML).start(); 

一切正常,我想。 Timer創建一個新的SwingWorker實例並執行它。工人完成後,新的工作被創建並執行。

我感到困惑的是,在工作線程完成後,我仍然可以看到它在Netbeans的調試窗口(例如SwingWorker-pool-3-thread-1)中運行,或者在Windows任務管理器(線程完成後,正在運行的線程數量不會減少)。 SwingWorker線程的數量限制爲10,但讓他們尷尬我。

在簡單的線程使用的情況下:

Thread th = new Thread(new Runnable() { 

    public void run() { 
     int a = 0; 
    } 
}); 
th.start(); 

該線程將自動執行後消失。

此SwingWorker行爲是否正常?

回答

11

是的,這是正常的。正如線程的名字所暗示的那樣,揮杆工人的模型(後臺)動作被委託給thread pool。工作完成後,線程返回到池中,以便其他工作人員可以使用它。這消除了創建/銷燬可能很昂貴的線程的一些開銷。

順便說一句,後臺線程不會永遠存在。縱觀源SwingWorker我看到:

//from SwingWorker.java (c) Sun Microsystems/Oracle 2009 
executorService = 
      new ThreadPoolExecutor(1, MAX_WORKER_THREADS, 
            10L, TimeUnit.MINUTES, 
            new LinkedBlockingQueue<Runnable>(), 
            threadFactory); 

這表明該線程將在空閒10分鐘後死去。

相關問題