2009-05-03 63 views
2

我對跨線程發佈數據和數據更改有一般疑問。 考慮下面的例子。跨線程的對象可見性

public class DataRace { 
    static int a = 0; 

    public static void main() { 
    new MyThread().start(); 
    a = 1; 
    } 

    public static class MyThread extends Thread { 
    public void run() { 
     // Access a, b. 
    } 
    } 
} 

讓我們關注main()。

顯然

new MyThread().start(); 
a = 1; 

有我們改變了MyThread的啓動後,共享變量,因此可能不是線程安全的出版物。

a = 1; 
new MyThread().start(); 

不過這次是在變化被安全地跨越新的線程公佈,由於Java語言規範(JLS)保證這是一個線程A可見,當它啓動一個線程B所有變量都可見線程B,它實際上就像在Thread.start()中有一個隱含的同步。

new MyThread().start(); 
int b = 1; 

在當兩個線程已經催生了後一個新的變量分配這種情況下,有沒有保證,新的變量將被安全地發佈到所有線程。即如果var b被另一個線程訪問,它是否保證看到它的值爲1.請注意,我不是在談論之後的任何後續修改(當然這需要同步),但是第一次分配完成由jvm。

感謝,

回答

0
a = 1; 
new MyThread().start(); 

分配到「A」會發生之前開始被稱爲在新的線程,因此,新的線程將始終打印的值「1」

new MyThread().start(); 
a = 1; 

在在這種情況下,MyThread可以打印1或0作爲'a'的值。

5

我是不是不完全知道這一個:

a = 1; 
new MyThread().start(); 

...在我不知道有任何保證之前的a值將是「刷新」到共享內存新的線程開始了。但是,規範明確地談到了這一點。在section 17.4.4中聲明:

啓動線程的動作與其啓動的線程中的第一個動作同步。

(之後的討論基本上表明,它會好起來的。)

我不知道你的最後一個例子(與b)的意思是什麼。

+0

當兩個線程產生後分配一個新變量時,是否保證新變量將安全地發佈到所有線程。即如果var b被另一個線程訪問,是否保證將其值設爲1? – baskin 2009-05-03 19:36:37

+0

這確實取決於確切的情況。必須有特定的東西來保證閱讀線程不使用緩存值,並且寫入線程已將寫入發佈到共享內存。有關更多(大腦消除)細節,請參閱上面參考的規範的第17章。 – 2009-05-03 20:10:22

0

MyThread()。start()啓動一個單獨運行的新線程。 int b = 1的聲明與您開始的線程無關。它繼續在主線程中。

如果兩個線程同時讀取或變異同一個對象,或者兩個線程以相反順序獲取資源上的鎖,以致每個線程都在等待另一個線程(這稱爲僵局)。

1

我不確定你在問什麼。我在認爲你在談論對「a」變量的線程安全訪問。

的問題是不是調用的順序,但事實上,

- 訪問到不是線程安全的。因此,在多線程更新和閱讀的示例中,您永遠無法保證您正在閱讀的「a」與您更新的值相同(某些其他線程可能已更改了該值)。

- 在多線程環境中,jvm不保證a的更新值保持同步。例如。

Thread 1: a=1 

Thread 2: a=2 

Thread 1: print a <- may return 1 

你可以通過聲明一個「volatile」來避免這種情況。

正如所寫,沒有任何關於a的價值的保證。

BTW,喬希布洛赫的Concurrency in Practice偉大書對這個問題(和我說,沒有得到所有的方式,通過它尚未;) - 它真的幫助我瞭解線程的問題,可以直接參與怎麼弄。

0

我有我的這個問題:)關於執行的併發線程之間共享資源的訪問

問題是一個相當容易理解和研究課題的疑慮。

通常,如果您有一個通過多個線程以讀/寫語義進行訪問的源,則需要管理對該資源的訪問。 (這裏的資源是靜態int變量DataRace.a)

(我也+1史蒂夫B.注這裏,這裏的問題不是調用的順序。)

0

如果b爲本地如代碼片斷所示,在DataRace.main()中創建的變量,MyThread無法訪問它,所以問題沒有實際意義。

如果b是主線程和MyThread線程之間的共享變量,它沒有正確的內存屏障時沒有正確的可見性,所以MyThread可能無法及時看到正確的值。