2010-11-03 187 views
5

作爲補充,以我目前的應用程序,我需要創建一個單獨的線程將定期做一些處理線程;創建一個單獨的線程來定期地做一些事情

我已經創建一個新的類來做到這一切,這個類將在我的應用程序啓動時加載。

這是我到目前爲止有:

public class PeriodicChecker extends Thread 
{ 
    static 
    { 
     Thread t = new Thread(new PeriodicChecker()); 
     while(true) 
     { 
      t.run(); 
      try 
      { 
       Thread.sleep(5000l); 
      } 
      catch (InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
     } 
    } 

    /** 
    * Private constructor to prevent instantiation 
    */ 
    private PeriodicChecker() 
    { 

    } 

    @Override 
    public void run() 
    { 
     System.out.println("Thread is doing something"); 
     // Actual business logic here, that is repeated 
    } 

} 

我想使構造私有,以防止其他人試圖意外實例化這個類。我怎樣才能做到這一點?

另外,在執行這些要求方面有什麼不好嗎?我只創建一個線程,然後運行然後睡覺,我是否錯過了任何明顯的東西?我之前沒有使用線程

+1

在靜態塊中啓動線程? :) – willcodejavaforfood 2010-11-03 11:04:32

回答

9

你有一些概念上的錯誤回報在你的代碼...比如:

  • 您應調用start()和不能運行(),因爲你同時運行方法的順序,而不是。
  • 您可以在每次循環迭代中只調用一次start(),而不是一次。在此之後,線程狀態終止,您應該創建一個新的線程來運行它再次
  • 你不應該建立在靜態塊中的線程,這是一個不好的做法,也許線程運行,你想讓它之前跑步。

您應該閱讀一些關於線程的示例,在開始處稍微難以忽略,並且您可能非常容易產生不期望的效果。

這裏是一個小例子,可以做一些類似的東西,你想:

public class PeriodicChecker extends Thread 
{ 
    @Override 
    public void run() 
    { 
     while(true) { 
      System.out.println("Thread is doing something"); 
      Thread.sleep(5000); 
     } 
    } 

} 

public OtherClass { 
    public static void main(String args[]) { 
     Thread t = new PeriodicChecker(); 
     t.start(); 
    } 
} 

如果你想無人能創建一個新的線程,你可以創建一個單例,所以你一定會認爲沒有人創建更多線程。

+0

有一個「}」 while循環後失蹤:) – Keshav 2011-07-08 08:51:37

+0

我固定的花括號,謝謝。 – greuze 2011-08-10 09:12:41

3

首先回答你的具體問題,你已經實現了你的目標。你已經聲明你的構造函數是私有的,沒有外部類可以像new PeriodicChecker()那樣調用它。在你的代碼

展望但是,也有一些其他的問題:

首先,你自己的靜態構造函數中創建類的實例。靜態構造函數的目的是初始化你的類可能擁有的任何靜態,你的類的哪些實例可能依賴它。通過在的靜態構造函數中創建類的實例,所有這些保證都會超出窗口。

其次,我不認爲你的線程會按照你期望的方式行爲,主要是因爲你實際上並沒有啓動另一個線程:)。如果您打算啓動一個新線程,則需要調用該線程對象上的start()方法。像你一樣調用run()實際上並不創建新線程,只是在當前線程中運行run()方法。

現在當你想創建一個新的線程來做某件事時,實現這個目的的方法不是擴展Thread,而是實現Runnable接口。這使您可以將線程的機制與您打算運行的行爲分離。

根據您的要求,我建議您取消這樣的頂級課程,而是在您的應用程序啓動代碼中創建一個私人內部課程,或者創建一個匿名內部課程:

public class Main { 

    public static void main(String[] args) { 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       while(true) { 
        System.out.println("Thread is doing something"); 
        Thread.sleep(5000); 
       } 
      } 
     }).start(); 
    } 

} 
2

這是幾乎從來沒有權利延伸Thread。如果你發現自己在做這件事,請退後一步,看看自己是否真的需要改變Thread課程的工作方式。

幾乎所有 occurances在那裏我看到extends Thread工作會做得更好實現Runnable界面或使用某種形式的Timer

12

Java提供ScheduledExecutorService來延遲調度和運行週期性任務或任務。它應該提供您需要的所有功能。計時器是另一個類,提供相似的功能,但我會建議在定時器ScheduledExecutorService的配置和更好的錯誤管理的靈活性。