2011-08-19 132 views
1

我有這樣Java線程運行

boolean start = false; 
    ThreadX a = new ThreadX(); 
    a.start(); 
    start = true; 

    Class ThreadX extends Thread { 

      public void run() { 
       while (start == true) { 
       ... 
       } 

      } 
    } 

代碼是否有與此代碼的問題嗎?我已經執行了這個,並沒有看到任何問題只是想得到一個掛起線程是否會啓動,永遠不會執行start = true

+0

用'擴展Runnable'替換'擴展線程' –

+1

@Eng:你的意思是'implements Runnable'。 – Jonah

+1

以及@Eng,Thread已經實現了Runnable,所以OP在這方面很好,但還有其他問題(例如,啓動應該是volatile)。 –

回答

3

是的,有一個問題。

假設start是一個局部變量,因爲所有在內部類中使用的局部變量必須是final,所以此代碼甚至不會編譯。

假設start是某個類的字段。然後該字段必須聲明爲volatile,否則不保證如果一個線程更改該變量,其他線程將看到該更改。

1

這取決於startrun()開始之前或之後變爲真。我說「這取決於」,因爲JVM沒有保證要麼是這樣。當然,這是假設start在您的線程實例的範圍內。

6

有兩個問題:

  • 首先線程在理論上可以開始start之前曾經設置爲true,因而立即終止。
  • 其次,線程理論上可以在start設置爲true後啓動,但由於缺乏內存屏障,從未將值設置爲start(假設它在原始線程中的某處設置爲false)。使變量volatile,使用鎖定或使用java.util.concurrent.atomic中的AtomicXXX類型之一(例如, AtomicBoolean

也爲良好的實踐中,你應該實現Runnable代替extening Thread - 你不想改變線程的基本行爲,你只是想提供它的任務。 (您可以延長線要做到這一點其實是設計缺陷IMO)

0

與此不保證該循環永遠不會進入:

如果線程啓動,並且當前線程(啓動另一個線程的線程)被中斷,因此另一個線程可以運行while條件將爲false,並且運行將退出

另一方面,如果當前線程未被中斷並且設置開始爲真,則循環將進入

這被稱爲競賽條件

0

線程將啓動,但可能immedietly退出,退出後,還是永遠運行:

方案1 - 線程運行前永遠 運行()進入,開始更新爲真實和JVM決定寫到內存,所創建的線程將會看到它爲真,並且永遠不會終止。()開始啓動之前更新爲true,但jvm不更新物理內存(no membar),然後繼續運行並看到false,並終止運行(或運行) )並且在運行start = true之前循環運行。

場景3 - 在run()或run()start更新之前的某個點 處退出,但jvm在運行多次迭代之後的某個點更新物理內存。