2011-02-05 77 views
2

我正在編寫一個涉及多線程工作程序池Process es的Java程序。類Process的每個實例都需要能夠產生一個額外的線程來完成一些工作。但是線程應該由實例本身和其他人產生。不幸的是Runnable.run是'公開',所以我不能真正執行這個沒有做一些伎倆。Java:在'Runnable'類中私下調用'run'

這裏是我計劃使用的伎倆:

  1. 實現RunnableProcess
  2. 寫這篇進入實施:

代碼:

class Process implements Runnable { 

    private boolean threadkey = false; 

    public void run() { 

     synchronized(threadkey) { 

      // is someone wrongly calling 'run'? 
      if(!threadkey) 
       return; 

      /* switch off threadkey to make sure 
      it cannot be called meaningfully again */ 
      threadkey = false; 
     } 
     /* continue processing 
     * 
     */ 
     return; 
    } 

當然,現在我只需要就可以做合法地是在撥打電話之前打開'threadkey'(這是私人的)。

優雅?或不?或者,還有更好的方法?或者我應該只是不打算強制執行此操作,並寫一個簡潔的小解釋,解釋不稱爲「運行」?

人們甚至會在需要做'跑步'的班級裏打'跑'嗎?

回答

10

雖然您確定Runnablerun方法是公開的,但您可以做的一件事是阻止其他人調用它,這樣可以使您的整個Runnable實現成爲包私有類或私有內部類。這樣,雖然它可能有一個publicrun方法,但您的自定義類以外的代碼不能實例化Runnable對象。如果您的班級還沒有交回對其的引用,則客戶端將無法訪問Runnable,因此他們無法調用run。也就是說,沒有你的Process類實現Runnable;取而代之的是,創建另一個實際實現Runnable的類,然後使Process成爲唯一可以訪問它的類。

這種方法比您提出的方法更優雅,因爲它可以防止其他代碼在編譯時調用run而不是在運行時。特別是,如果任何代碼試圖調用上述的run方法,它將編譯得很好,並且在運行時會失敗。問題是代碼會編譯,但永不正常工作。使Runnable不可訪問意味着如果某人確實嘗試運行它,則會產生編譯時錯誤,並且將不得不重新考慮其設計。換句話說,編譯器會在它發生之前檢測到錯誤。

一般來說,如果您發現自己希望防止隨機代碼調用必須公開的類的方法,因爲它們在接口中聲明,請考慮更改整個類的訪問說明符,以便客戶端可以沒有參考它。

6

您可以使用匿名內部類的Runnable這樣的:

private void spawnThread() { 
    Thread t = new Thread(new Runnable(){ 
      public void run(){ 
      // do something 
      } 
    } 
    t.start(); 
} 

而且spawnThread()只能從類中調用,因爲它是私有的。

1

你可以有你的run()方法私有的,並使用一個內部類(實現Runnable)來訪問它:

public class Process { 

    private Thread extraThread = null; 

    private void run() { 
     // Do you thing 
    } 

    public synchronized void spawnExtraThread() { 
    if(extraThread != null) 
     return; // Do nothing an extra thread was already spwaned 
    extraThread = new Thread() { 
     public void run() { Process.this.run(); } 
    }; 
    extraThread.start(); 
    } 
} 

主要的一點是,級製程()不再實現Runnable,因此可以不再變成一個線程。當然,你擴展這個設計來支持對線程數量的任何限制(只需將extraThread字段更改爲一個線程數組)。

相關問題