2014-05-05 22 views
1

是可以安全使用AtomicBoolean非阻塞鎖的讀取和寫入訪問從多個線程不是線程安全的數據,利用建築:的AtomicBoolean後衛不是線程安全的數據(揮發性捎帶)

if (lock.compareAndSet(false, true)) { 
    try { 
    //Access non-volatile fields, non-atomic arrays and not thread-safe classes 
    } finally { 
    lock.set(false); 
    } 
} else { 
    //Access denied, try again later or right now 
} 

這個結構以外的數據不可用。由於不穩定的捎帶效應,我幾乎可以肯定它是安全的。我對嗎?

回答

3

高層次的考慮必須是它是否安全地排除併發訪問關鍵資源。這工作作爲AtomicBoolean提供了必要的保證。作爲一個重要的規則,JMM的設計方式是,如果你正確地實現了高級邏輯,那麼低級別的東西也會如此。

在您的問題中進一步細化,volatile讀取和寫入排除意外重新排序,就像您期望的那樣(又稱「捎帶」)。

你基本上在做什麼Lock也做。 A ReentrantLock將使用int而不是boolean,並且Lock提供等待隊列,其中簡單的原子變量不包含。

AbstractQueuedSynchronizer顯示瞭如何在一個原子int變量周圍實現該邏輯(與您的類似)。

+0

+1這是有保證的,因爲「*訪問和更新原子的記憶效應通常遵循揮發物的規則。」([ref](http://docs.oracle.com/javase/7/docs/ API/JAVA/util的/並行/原子/包summary.html))。 – assylias

+0

是的,但即使在塊條目處的易失性讀取對於記憶效應也足夠了,儘管它不會妨礙併發訪問。不要忘記塊末尾的易失性寫入。 – Holger

+0

我現在看到!我應該將'AtomicBoolean'改爲'ReentrantLock',並在我的構造中調用'tryLock()'和'unlock()'方法。謝謝! – FireFry