2011-03-01 7 views
11

मैं एक कंसोल अनुप्रयोग के लिए एक जीयूआई लागू कर रहा हूं, और मुझे निर्दिष्ट समय अंतराल में कुछ क्रियाएं करने की आवश्यकता है (उदाहरण के लिए, एक XML फ़ाइल पार्स करें)। मैंने यह सुनिश्चित करने के लिए स्विंगवर्कर के साथ javax.swing.Timer का उपयोग करने का निर्णय लिया है कि ये क्रियाएं मेरे आवेदन को उत्तरदायी नहीं बनाती हैं।मेरा स्विंगवर्कर थ्रेड क्यों चल रहा है भले ही वे निष्पादित किए गए हों?

मैं टाइमर इस तरह से लागू किया:

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

सब कुछ काम करता है मैं चाहता हूँ के रूप में। टाइमर नया स्विंगवर्कर उदाहरण बनाता है और इसे निष्पादित करता है। कार्यकर्ता के पूरा होने के बाद, नया बनाया और निष्पादित किया जाता है।

जिस चीज को मैं उलझन में डालता हूं वह यह है कि कार्यकर्ता के धागे के बाद भी मैं इसे नेटबीन्स की डिबगिंग विंडो (उदाहरण के लिए, स्विंगवर्कर-पूल-3-थ्रेड -1) या विंडोज टास्क मैनेजर में देख रहा हूं (धागे के बाद चलने वाले धागे की संख्या में कमी नहीं होती है)। स्विंगवर्कर धागे की संख्या 10 तक सीमित है, लेकिन उन्हें मुझे शर्मिंदा कर रहा है।

सरल धागा उपयोग के मामले में:

Thread th = new Thread(new Runnable() { 

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

यह धागा स्वचालित रूप से निष्पादन के बाद गायब हो जाता है।

क्या यह स्विंगवर्कर व्यवहार सामान्य है?

उत्तर

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 मिनट के लिए निष्क्रिय होने के बाद बंद मर जाएगा।