2013-02-21 58 views
2

我通常看到兩種方法來實現一個守護進程,它會執行一些工作並進入睡眠狀態並再次喚醒。哪種方法更好的遵循以下兩種方法來安排和停止線程

  1. while(flag)的方法,其中flag爲true,如果我們想停止守護進程,則被其他類設置爲false。

    while(flag){ 
        //do something 
        Thread.sleep(10000l); 
    } 
    
  2. 使用固定延遲調度ScheduledThreadPoolExecutor。

國際海事組織,第二種方法是更清潔和易於測試。有人可以比較這兩種方法。可以先解決任何內存問題?

謝謝

回答

2

方法2)被推薦。

方法之一不是由基礎線程系統(尤其是在UNIX上)強大的隨機覺醒,你也需要實現自己的錯誤處理

方法有兩個可以讓你從底層的Thread和工作與RunnableCallable

而且方法1)具有時鐘漂移的問題,即你的任務需要一個非零時間,因此執行將執行每十秒鐘。 ScheduledExecutorService實際上會每秒執行一次執行,或者如果需要,每十秒鐘執行一次執行。

方法2)提供了一種簡單的方法來安排線程在一段時間內執行某些操作,並按照javadoc中的示例將其殺死。

最後,ExecutorSevice更容易關閉自定義線程,只需調用executorService.shutdown()然後executorService.awaitTermination()即可等待最後一個任務完成。

您可能需要注意的一件事是javadoc中的這個gem - 「如果任務的任何執行遇到異常,則後續執行被取消」。這意味着要麼你必須非常小心你的Callabletry/catch或者你需要這樣子類ScheduledExecutorService(從javadoc中獲取):

public class MyScheduledExecutor extends ScheduledThreadPoolExecutor { 

    public MyScheduledExecutor(int corePoolSize) { 
     super(corePoolSize); 
    } 

    @Override 
    protected void afterExecute(Runnable r, Throwable t) { 
     super.afterExecute(r, t); 
     if (t == null && r instanceof Future<?>) { 
      try { 
       Object result = ((Future<?>) r).get(); 
      } catch (CancellationException ce) { 
       t = ce; 
      } catch (ExecutionException ee) { 
       t = ee.getCause(); 
      } catch (InterruptedException ie) { 
       Thread.currentThread().interrupt(); // ignore/reset 
      } 
     } 
     if (t != null) { 
      System.out.println(t); 
     } 
    } 
} 
+0

+1好點。除了最後一段不適用,因爲OP對固定延遲而不是固定費率的調度方案感興趣。 – 2013-02-21 10:09:17

3

可以先接近造成任何內存問題?

不是。最大的問題是管理flag變量的可見性。每當我看到有人提出這種方法時,我立即就投下它。由於某種原因,Thread類封裝了中斷標誌的概念。