2011-04-20 22 views
1

如果兩個線程同時嘗試訪問相同的易失性變量,會發生什麼情況。在這種情況下什麼類型的鎖。 請幫我解決這個疑問。Java中多線程應用程序之間的易失性成員

+0

「access」是指讀或寫? – 2011-04-20 22:19:54

+0

請參閱相關http://stackoverflow.com/questions/3038203/is-there-any-point-in-using-a-volatile-long – 2011-04-20 22:47:58

回答

4

這可能會幫助您:

  • 這個變量的值將不會被線程本地緩存:所有讀取和寫入將直接進入「主內存」
  • 訪問變量行爲就像它被包含在一個同步塊中一樣,同步於它本身。

我們說「的行爲如同」第二點,因爲程序員至少(可能在大多數JVM實現)沒有實際鎖定對象參與

來源:http://www.javamex.com/tutorials/synchronization_volatile.shtml

1

我有一個short text snippet爲你解釋volatile變量。

易失性變量不會被緩存在寄存器或緩存中,因爲它們對其他處理器是隱藏的,所以讀取易失性變量總是返回任何線程的最新寫入。

然而訪問volatile變量不會執行鎖定,因此不會導致執行線程阻塞,使volatile變量成爲比同步更輕的同步機制。

實施例:

當線程A向其寫入的易失性 變量,並且隨後線程B 讀取相同的變量,其值表示寫入易失性 甲之前是可見的,以 所有變量的 在 讀取易失性變量後,變量對B可見。

1

在單CPU的機器有沒有這樣的事情「同時」 - 操作系統(OS)調度每個線程被移動到之前的短時間內執行下一個線程。

在多CPU(SMP)的機器,兩個CPU可以同時執行代碼,但Java Language Specification(JLS)提供了有關volatile領域的保證,所以你仍然可以編寫正確的多線程代碼。

但從程序員的角度來看,有沒有鎖與volatile領域打交道時參與。忽略其中兩個線程正在讀取場無趣的情況下(擾流板:能看到相同的值),我們有兩種情況:

  1. 一個線程讀取,其他更新:讀者將看到此舊的或新的價值根據其中兩個線程由OS調度
  2. 兩個線程更新的順序:現場將最終持有爲準線的值被安排最近

要注意這一點很重要:

  • 即使字段類型爲long,佔用8個字節的內存,JLS保證,在volatile字段中,讀者將永遠不會看到(例如)4個字節的「舊」值和4個字節的「新」 - 這是全有或全無
  • 所有線程調度更新後會看到新的價值立即

這些都不是必要的非volatile領域如此。

+0

+1是連接到JLS的唯一答案 – 2011-04-21 08:40:58

0

無論如何,大多數可變寫操作都是原子操作,但volatile會確保在另一個線程嘗試訪問它之前將該值完全寫入內存區域,並且還確保線程不會將變量緩存爲速度(上下文切換可能是昂貴的,所以解釋者可能會採取一些事情來獲得速度)。如果沒有指定volatile,可能會出現這樣的情況,即兩個不同的線程在任何時候都可能具有不同的有關變量值,這可能會使事情變得嚴重。

這是一個很好的閱讀:http://expertdevelopers.blogspot.com/2011/03/atomicity-thread-safety-in-java.html