java meomry模型要求synchronize
在同一個監視器上同步的塊在這些塊內修改的變量之前強制執行之前的事後處理。例如:Java內存模型:重新排序和併發鎖定
// in thread A
synchronized(lock)
{
x = true;
}
// in thread B
synchronized(lock)
{
System.out.println(x);
}
在這種情況下,它保證下,該線程B將看到x==true
只要線程A已經通過了- 嵌段。現在我正在重寫大量代碼,以便使用java.util.concurrent
中更靈活(並且更快)的鎖,特別是ReentrantReadWriteLock
。因此,本例看起來像:
編輯:這個例子被打破了,因爲我錯誤地改變了代碼,由亞光指出b。修正如下:
// in thread A
lock.writeLock().lock();
{
x = true;
}
lock.writeLock().unlock();
// in thread B
lock.readLock().lock();
{
System.out.println(x);
}
lock.readLock().unlock();
不過,我還沒有看到內存的型號規格內的任何暗示,這種鎖也意味着nessessary排序。縱觀實現,它似乎依賴於訪問AbstractQueuedSynchronizer
內部的易變變量(至少用於太陽實現)。然而,這不是任何規範的一部分,而且對這些變量給出的內存屏障並沒有真正考慮對非易失性變量的訪問,是嗎?
所以,這裏是我的問題:
- 它是安全的假設相同的順序與「老」塊?
- 這是否記錄在某處?
- 正在訪問任何易變變量的內存屏障的任何其他變量?
問候, 斯特芬
-
註釋Yanamon:
請看下面的代碼:
// in thread a
x = 1;
synchronized (a) { y = 2; }
z = 3;
// in thread b
System.out.println(x);
synchronized (a) { System.out.println(y); }
System.out.println(z);
從我的理解,記憶障礙強制執行第二個輸出顯示2,但對其他變量沒有保證影響...?那麼如何才能比較訪問一個易變的變量?
關於你添加的代碼的一個說明,線程b將只打印2,如果它獲得了線程之前的鎖定...這是暗示的,但我只是想說清楚。 但是要回答您不穩定的問題,請按以下方式使用volatile來強制執行可見性: -------- volatile boolean memoryBarrier = false; int unguardedValue = 0; //線程a: unguardedValue = 10; memoryBarrier = true; //線程b 如果(memoryBarrier){unguardedValue被保證讀爲10; } – Yanamon 2010-04-05 01:56:23
嗯,我認爲在評論中編寫代碼並不是很好,我用一個示例更新了我的答案 – Yanamon 2010-04-05 02:07:31