2011-05-28 29 views
5

在一個swing應用程序中,我想重新利用一個派生線程,而不是創建一個新的服務請求。這是因爲請求會在很短的時間間隔內完成,並且爲每個請求創建新線程的成本可能很高。使用sleep()和interrupt()來重用線程

我想使用中斷()和睡眠()方法如下做到這一點的,想知道的代碼的任何潛在的性能問題:

public class MyUtils { 
    private static TabSwitcherThread tabSwitcherThread = null; 

    public static void handleStateChange(){ 
     if(tabSwitcherThread == null || !tabSwitcherThread.isAlive()){ 
      tabSwitcherThread = new TabSwitcherThread(); 
      tabSwitcherThread.start(); 
     } 
     else 
      tabSwitcherThread.interrupt();  
    } 

    private static class TabSwitcherThread extends Thread{ 
     @Override 
     public void run() { 
      try { 
       //Serve request code 

       //Processing complete, sleep till next request is received (will be interrupted) 
       Thread.sleep(60000); 
      } catch (InterruptedException e) { 
       //Interrupted execute request 
       run(); 
      } 

      //No request received till sleep completed so let the thread die   
     } 
    } 
} 

感謝

+1

實際上,我認爲你是TabSwitcherThread會得到計算器例外早晚,因爲你有你的run()方法遞歸調用:) – Alvin 2011-05-28 09:38:19

回答

4

我想你要找的是一個ThreadPool。 Java 5及以上版本附帶ThreadPoolExecutor。我建議你使用Java提供的而不是自己寫的,這樣可以節省很多時間和頭髮。當然,如果你絕對必須按照你所描述的方式來做(嘿,有時候業務需求會讓我們的生活變得艱難),那麼就按Jon所建議的那樣使用wait()和notify()。在這種情況下,我不會使用sleep(),因爲您必須指定超時時間,並且您永遠不知道下一個請求何時會進入。讓一個線程繼續醒來然後再回到睡眠狀態似乎對我來說有點浪費CPU週期。

這是關於ThreadPoolExecutor的nice tutorial

編輯:

下面是一些代碼示例:

public class MyUtils { 
    private static UIUpdater worker = null; 
    private static ExecutorService exeSrv = Executors.newFixedThreadPool(1); 

    public static void handleStateChange(){ 
     if(tabSwitcherThread == null || !tabSwitcherThread.isAlive()){ 
      worker = new UIUpdater(); 
     }  

     //this call does not block 
     exeSrv.submit(worker, new Object());  
    } 

    private static class UIUpdater implements Runnable{ 
     @Override 
     public void run() { 

      //do server request and update ui. 
     } 
    } 
} 
10

我不會如果我絕對必須使用sleep()interrupt() - 我會使用wait()notify()

但是,是否真的需要這樣做而不是使用可以處理線程重用的ThreadPoolExecutor?或者在生產者/消費者時尚中使用BlockingQueue

Java已經爲此提供了足夠的高級構建模塊,您不需要自己去這個級別。

+0

感謝您的回覆。這是一個小型的Java應用程序,我不想讓'n'線程集中處理請求。基本上,一次會有單個請求進來。情況就像在textarea中,用戶鍵入一些東西,這需要處理。我不能在同一個線程中做,因爲它會導致UI凍結,因此需要單獨的thead。爲此,我想有一個專用的線程,並避免創建新的線程,因爲我在創建新線程方面經歷了相當長的延遲。謝謝! – skk 2011-05-28 09:32:07

+1

@skk 1個線程池有什麼問題? :)。我用一個如何利用Java併發框架的示例代碼修改了我的答案。我借用了部分代碼,希望你不介意。 – Alvin 2011-05-28 09:52:11

+2

@skk:一個生產者/消費者隊列可以爲你做,或者一個線程的'ThreadPoolExecutor'。 – 2011-05-28 10:16:40