[英]Java multi-threading accessing same variable
我有一個Java程序,該程序創建2個線程,在這2個線程中,它們試圖將全局變量abc
更新為不同的值,例如整數1和整數3。
假設他們在同一時間(同一毫秒)執行代碼,例如:
public class MyThread implements Runnable{
public void run(){
while(true){
if (currentTime == specificTime){
abc = 1; //another thread update abc to 3
}
}
}
}
在這種情況下,我們如何確定變量abc
的結果? 我很好奇操作系統如何安排執行時間?
(我知道應該使用同步,但是我只想自然地知道系統將如何處理這種沖突問題。)
操作系統對此幾乎沒有參與:在線程運行時,分配給abc
的內存在運行程序的JVM的控制下,因此程序是受控制的。
當兩個線程訪問相同的內存位置時,最后一個寫入程序獲勝。 但是,除非您使用同步,否則哪個特定線程將成為最后一個寫程序是不確定的。
此外,如果您不特別注意訪問共享數據,則一個線程甚至可能看不到另一線程寫入abc
位置的結果。
為避免同步問題,應使用同步或java.util.concurrent.atomic
類之一。
從Java的角度來看,如果abc
不是易失性的或通過適當的同步訪問的,則情況相當簡單。
假設abc
最初是0。 在兩個線程分別將其更新為1和3之后,可以在三種狀態下觀察abc
:0、1或3。獲得的值不是確定性的,一次運行的結果可能會不同。
取決於操作系統,運行環境等。
某些環境實際上會阻止您執行此操作-稱為線程安全。
否則結果是完全不可預測的,這就是為什么這樣做如此危險的原因。
它主要取決於最后更新哪個線程的值。 一個線程將在其他線程首先執行原子操作之前獲得CPU周期。
另外,我不認為操作系統可以安排線程,因為在大多數操作系統中,是由程序負責它們,並且沒有像同步之類的顯式調用或線程池模型,所以我認為執行很難預測。 它是非常依賴環境的。
從系統的角度來看,結果將取決於許多軟件,硬件和運行時因素,而這些因素是無法事先知道的。 從這個角度看,沒有沖突也沒有問題。
從程序員的角度來看,結果不是確定性的,因此是一個問題/沖突。 沖突需要在設計時解決。
在這種情況下,我們如何確定變量
abc
的結果? 我很好奇操作系統如何安排執行時間?
結果將不確定,因為該值將是最后寫入的值。 您不能保證任何結果。 計划執行與其他任何執行一樣。 由於您不需要代碼同步,因此JVM不會為您執行任何操作。
我知道應該使用同步,但是我只想自然地知道系統將如何處理這種沖突問題。
簡單地說:它不會,因為系統沒有沖突。 僅對於您(程序員)而言,問題就會發生,因為您最終將陷入數據爭奪而不是確定性的行為。 這完全取決於你。
只需將volatile修飾符添加到您的變量中,即可在所有線程中進行修改。 並且線程讀取它會得到它的實際值。 volatile
意味着該值對於所有訪問它的線程而言始終是最新的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.