2011-03-01 26 views
11

Konsol uygulaması için bir GUI uyguluyor ve belirli bir zaman aralığında bazı eylemler (örneğin, bir XML dosyasını ayrıştırma) yapmam gerekiyor. Ben bu eylemleri yanıt vermem yanıt vermeyeceğinden emin olmak için SwingWorker ile birlikte javax.swing.Timer kullanmaya karar verdim.SwingWorker iş parçacıklarım neden yürütülürken çalıştırılıyor?

Ben, saat ve alarm bu şekilde hayata geçirdiklerini:

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

... ve şu şekilde kullanın:

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

Her şey istediğiniz gibi çalışır. Zamanlayıcı yeni bir SwingWorker örneği oluşturur ve bunu yürütür. İşçi yapıldıktan sonra yenisi oluşturulur ve yürütülür.

Kafam karıştıran şey, işçinin iş parçacığı bittikten sonra hala Netbeans'ın hata ayıklama penceresinde (örneğin, SwingWorker-pool-3-thread-1 olarak) veya Windows Görev Yöneticisi'nde çalışmakta olduğunu görebiliyorum. (iş parçacığı bittikten sonra çalışan iş parçacığı sayısı azalmaz). SwingWorker iş parçacığı sayısı 10 ile sınırlıdır, ancak sahip olmak beni utandırıyor. Basit iplik kullanımı durumunda

:

Thread th = new Thread(new Runnable() { 

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

Bu iplik geldikten sonra otomatik olarak kaybolur.

Bu SwingWorker davranışı normal midir?

cevap

11

Evet, bu normaldir. İş parçacığının adından da anlaşılacağı gibi, salıncak çalışanlarının modeli (arka plan) eylemleri thread pool'a aktarılıyor. İş bittiğinde, iş parçacığı havuza geri döner, böylece başka bir çalışan bunu kullanabilir. Bu, pahalı olabilecek iplik oluşturma/imha etme konusunda bazı ek yükleri ortadan kaldırır. Bu arada, arka plan konuları sonsuza kadar kalıplanmayacaktır. SwingWorker için kaynak baktığımızda görüyorum:

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

Bu konu 10 dakika boyunca boşta kaldıktan sonra kapalı ölecek olduğunu gösterir.

İlgili konular