2017-04-11 241 views
0

我有一個簡短的while循環一樣:while循環停止檢查if語句?

boolean a = false; 
MyClass b = new MyClass(); 
b.b = false; 

// b is used in other thread... 

while(!a){ 
    if(b.b){ 
     throw new Exception("b is true"); 
    } 
} 

在這種情況下a永遠不會成真,但一些運行後布爾變量b.b應該成真。奇怪的是,while循環從未離開過,我的程序無限循環。

我woundered爲什麼決定到System.out.print語句添加到循環:

while(!a){ 
    if(b.b){ 
     throw new Exception("b is true"); 
    } 
    System.out.println("there is something more to execute"); 
} 

值得注意的是我的代碼就像是應該的。 while循環遍歷if語句,直到b.b爲真,並拋出異常將退出循環。

難道是在第一種情況下,程序停止檢查if語句,因爲編譯器認爲它沒有必要再次檢查?如果沒有,有人可以向我解釋,爲什麼第一個案件不起作用,但第二個案件呢?

+0

如何在線程之間同步b.b? – bowmore

+1

如果b.b在你的if裏面是真的,爲什麼不使用break或set a爲真?針對預期的行爲拋出異常並不是很好的設計。 –

+1

也許向我們展示b如何在另一個線程中使用 –

回答

6

如果您正在使用多線程環境,則需要將您的變量(無論哪個人都可以訪問多個線程)標記爲volatile,否則,不能保證當前線程能夠看到其他線程寫入的結果。

換句話說,一個線程寫入(更改)變量的值a,而另一個線程不能保證看到它(因爲線程可能會複製/緩存變量),這會導致您的環路不能中斷。

我建議你看看here並瞭解volatile如何在多線程環境中工作。下面的文本(重點煤礦)從相同的鏈接採取:

更改爲volatile變量總是給其他線程可見。當一個線程讀取一個volatile變量時,它不僅會看到對volatile的最新更改,還會看到導致更改的代碼的副作用。

+0

感謝您的回答。我不知道這種行爲。也描述在http://stackoverflow.com/questions/25425130/loop-doesnt-see-changed-value-without-a-print-statement – team17

+0

沒問題,'volatile'是一個基本的概念,但一個重要的 – developer