2012-11-14 60 views
4

我想有一個標誌,可以從不同線程讀取/寫入,而不會出現髒值問題。它足以使其靜態變化嗎?Java:是否有正確的方法來使用靜態易失性變量?

static volatile boolean flag; 
+2

我不確定它是否足夠,但我建議使用['AtomicBoolean'](http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic改爲/AtomicBoolean.html)。 –

+0

我會盡可能避免靜態可變字段。相反,我會使用AtomicBoolean傳遞給您想要標記的線程。 –

回答

5

不,如果你需要一個這樣的動作,這是不夠的:

volatile int v = 0; 

Thread 1: 
v++; 

Thread 2: 
v--; 

理想情況下,你要V = 0時,當你執行上面的代碼,但是這是真的發生了(一複合動作):

Thread 1: 
r1 = v; 
r2 = r1 + 1; 
v = r2; 

Thread 2: 
r3 = v; 
r4 = r3 - 1; 
v = r4; 

而且這兩個線程將分別給出值1和-1。來源:Volatile Does Not Mean Atomic!

如果你需要在mulithreaded場景中保證一致的結果,你應該在Java中使用Atomic類作爲@ Eng.Fouad指出的。

在boolean的情況下,比起使用volatile的比較和設置將有助於AtomicBoolean類。

+0

是的,它用於讀取,計算和保存數據的操作。但是,僅將讀/寫操作用作布爾變量是否正確? –

+0

我沒有得到。你問是否正確使用r/w操作? (我剛剛回答) – zengr

+0

不,我的意思是說我們有靜態易失標誌。然後我將它標記爲false,另一個線程讀取它,而其他線程將其標記爲true。在這種情況下,我會得到一個骯髒的價值觀? –

3

這很誘人,但避免這樣的代碼。

在一個簡單的情況下,這似乎工作,因爲boolean不允許任何數學操作(您只能給它分配值)。但你很少有簡單的例子。最終,您將需要

if(flag) { 
    flag = false; 
} 

並且此代碼有時會中斷。因此,正如其他答案所建議的那樣,您應該使用java.util.concurrent.Atomic *類。

相關問題