簡體   English   中英

Java多線程訪問相同的變量

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM