2010-11-11 91 views
0

我試圖按以下方式啓動/停止Java線程。Java:線程間變量的同步

public class ThreadTester { 
    public static void main(String[] args) { 
     MyThread mt; 
     int max = 3; 

     for (int i = 0; i < max; i++) { 
      mt = new MyThread(); 
      mt.start(); 
      mt.finish(); 
     } 
    } 
} 

public class MyThread extends Thread { 
    private volatile boolean active; 

    public void run() { 
     this.active = true; 
     while (isActive()) { 
      System.out.println("do something"); 
     } 
    } 

    public void finish() { 
     this.active = false; 
    } 

    public boolean isActive() { 
     return active; 
    } 
} 

一切正常只有最大< = 2。否則一些線程繼續他們的輸出,雖然isActive應該返回false。這至少是我的期望。

問題:什麼是可變的「高手」之間同步的正確方法和它的「奴隸」的主題?

+1

這將有助於解釋爲什麼你認爲,如果大豆> 2 – 2010-11-11 23:22:10

+0

基於代碼最高似乎是無關的,爲什麼它的失敗它不工作。 – 2010-11-11 23:24:24

+3

這個數字並非無關緊要。取決於內核數量和線程調度,假設你可能會啓動2個線程,但是第三個線程在run()發生之前調用它,完成調用 – 2010-11-11 23:25:51

回答

7

你應該聲明中初始化activetrue的,而不是run方法。

public class MyThread extends Thread { 
    private volatile boolean active = true; 

    public void run() { 
     // this.active = true; 
     while (isActive()) { 
      // do nothing 
     } 
    } 

    public void finish() { 
     this.active = false; 
    } 
} 

你這樣做的方式存在競爭條件。

此外,對於安全停止線程更好的辦法是使用中斷。

+0

+1,用於「安全停止線程的更好方法是使用中斷「,整個活動標誌的事情是多餘的。 – 2010-11-11 23:35:04

+0

謝謝亞歷山大,在構造函數中'active'的初始化做到了訣竅。 – MrG 2010-11-11 23:43:14

0

什麼不按預期工作?

我沒有看到從活動的成員,這是不是真的共享,作爲其私人事情在那裏導致用戶在線程同步的,除了......並自該修改將其設置爲false的唯一方法。

我可以看到的唯一的事情是,在線程運行之前,您可能會調用finish,隨着線程數的增加,這種情況會越來越多。

,如果你想你的線程停止前至少做一件事情,你可以在你的while循環切換到做,而不是:

do 
{ 
    // do nothign at least once 
} 
while(active); 

則每個線程檢查,看它是否應該停止前會做什麼。

2

當你說開始你是說線程準備執行,但run方法在那一刻不啓動(啓動時調度說)。所以,你很可能首先執行this.active = false,然後陷入無限循環。

+0

+1。很好,對因果關係的重點解釋。 – 2010-11-11 23:30:29

+0

謝謝,我理解你的評論。但我的問題是線程「繼續存在」,儘管它們不應該。 – MrG 2010-11-11 23:34:42

+0

那麼這不是一個問題,因爲,我傷心的時候,線程會卡在循環中並繼續活着。亞歷山大Pogrebnyak提供了正確的解決方案如何制止這一點。 – Klark 2010-11-12 10:00:55