2015-05-09 53 views
1

我開始與線程,信號量,volatile變量等 我不知道,當我使用信號燈則需要將變量定義爲揮發性,我的意思是:使用volatile變量和旗語 - Java的

有2個線程,一個增加,另一個減少變量,例如,很顯然,在每次訪問之前,我有一個互斥量,它隨時控制一個線程正在與變量「玩」。

,有必要將其定義爲volatile嗎?

+2

爲什麼不使用'AtomicLong'進行這樣的操作?在同一個整數上正確高效地執行併發操作並不容易。 JDK中有很多可用的類可以爲您完成這項工作。 –

+0

你爲什麼在這裏使用信號量? – Sandeep

回答

3

Semaphore API文檔:

內存一致性效果:調用 「釋放」方法之前,操作中的一個線索,例如release()發生,之前之後的 成功的「獲取」方法行動如另一個線程中的acquire()

因此,讀取/寫入由信號量保護的變量是安全的。

1

我不知道,當我使用信號燈有必要定義 變量揮發,

我不認爲有任何這樣的限制。互斥量是一種互斥信號量,一次只允許一個寄存器的信號量的特殊變體。它相當於一個計數爲1的正常計數信號量和只能由鎖定它的同一個線程釋放的要求。

如果我們專門爲Java中的Semaphore談論:信號量是許可證的計數器,並且獲取就像等待下降而不是低於零的遞減。它沒有上限。作爲CIP提到:

的實施有沒有實際的許可對象,和信號燈不 不是線程分配許可相關聯,所以在 一個線程獲得的許可證可以從另一個線程被釋放。你可以想象得到 作爲消費許可證和釋放作爲創建一個;一個 信號量不限於它創建的許可證數量。

對於您的情況,您可以共享一個計數器,並使其揮發或更好地利用AtomicInteger,因爲它們使用CAS機制,低競爭下執行得很好。

2

信號燈不應該同步,因爲信號燈的地方不成立,即使它被初始化爲一個,像一些對象上同步獨家互鎖使用。確實,信號量初始化爲1,一次只允許一個線程訪問持有許可證的對象。但持有許可證的線程不擁有它,任何其他線程可以釋放該許可證並獲得許可證。因此,兩個線程可以同時訪問同一個對象,並且如果兩個線程都操作該對象,將會出現多線程問題,例如丟失更新,陳舊讀取等。

在您的示例中有2個線程,一個增加並且一個減少相同的變量。互斥是足夠的,不需要揮發性聲明。在這裏我假設互斥是通過同步而不是通過信號量來實現的。

易失性不如同步,您可能希望在執行的操作是原子(讀取或寫入)時使用易失性。執行讀取更新編寫操作時不應使用volatile。

+0

爲什麼你認爲當他不使用同步的信號量時,通過同步來達到互斥的目的? – Shondeslitch

+0

,因爲在這個例子中,他說互斥體,從來沒有提到同步,問題是關於信號量和易失性。由於沒有明確提及,我希望他的意思是同步的,因爲在這種情況下信號量不適合 – Thilak