2011-03-02 72 views
11

如何製作一個陣列易失性?因爲正如我已經理解的那樣,使數組變得不穩定是不安全的。Java易失性數組?

+2

http://jeremymanson.blogspot。com/2009/06/volatile-arrays-in-java.html – 2011-03-02 21:21:50

回答

13

聲明數組volatile不會對其字段進行volatile訪問。你聲明的參考本身是不穩定的,而不是它的元素。

換句話說,你聲明瞭一組易失性元素,而不是一組易失性元素。 這裏的解決方案是在要使用整數的情況下使用AtomicIntegerArray。 另一種方式(但有點醜)是每次改寫參考陣列編輯字段

你做到這一點

arr = arr; 

(正如我所說的......醜)

+2

我不認爲正在揮發的元素與元素的訪問是原子相同的。 – Blindy 2011-03-02 21:26:15

+0

你說得對,'volatile'是關於保證發生之前的關係。 – mike 2013-08-09 10:55:51

6

AtomicLongArray,AtomicIntegerArray,AtomicReferenceArray(java.util.concurrent.atomic)。

1

編輯: 在java中的數組對象。如果您將該對象的引用設置爲volatile,那麼如果將引用交換到數組,則使其對其他線程可見。 但是,這並不適用於數組值本身。

爲了獲得更好的java內存模型,實際上有可能在沒有Atomic * Array的情況下繞過它。如果線程A在之後寫入一些非易失性內容和易失性變量,那麼線程B將保證看到易失性內容的變化而且只有在線程B首先讀取volatile變量的情況下。 還看到: Happens-before relationships with volatile fields and synchronized blocks in Java - and their impact on non-volatile variables?

對於數組,這意味着: 後寫入陣列,寫入一些揮發性狀態變量(請務必寫實際上改變了揮發性狀態變量!) 當你從陣列讀取,首先讀取volatile狀態變量,然後訪問數組。 易失性讀取應該使所有其他寫入都可見,只要它們發生在前面。

老: 寫自我參考arr=arr實際上不會幫助。

您寫入數組arr的地址,而不是字段arr[i]的值。因此,您仍不會獲得arr[i](您需要)的易失性屬性,但僅適用於存儲地址arr

傑里米·曼森前面提到的博文解釋得很詳細: http://jeremymanson.blogspot.com/2009/06/volatile-arrays-in-java.html

他最好的解決辦法是使用原子*陣列,即AtomicReferenceArray泛型類型(也存在特殊形式爲基本類型)。我無法想象這是特別有效的,尤其是因爲它爲您提供了更多您需要的屬性(原子性>>易失性)。

替代方案可能是容器使用易失性指針字段的指針結構。也沒那麼高效......