2012-01-15 24 views
2

我有一個複雜的地圖,它不需要鎖對於經常得到和偶發的變化,因爲這些密鑰唯一地確定它們的引用元素的行爲。的java:揮發性陣列發佈的數據變化

也就是說,如果密鑰是相同的,它引用的結構將始終具有相同的行爲。事實上,最終的關鍵是不變的,並且所引用的值實際上是最終的和/或線程安全的。

可以說,我有我的自定義HashMap中的揮發性參考引用的基本揮發陣列。我對這個數組的hashmap算法使用ar.length成員作爲模數,所以如果在get函數中調用者看到一個非當前數組,它的所有引用仍然是好的,並且仍然服從散列槽,所以如果它沒有互斥就能成功獲得非空值,這是正確的。

我的計劃是,每當一個GET操作失敗,調用者則構建了關鍵的正確值不認沽這確實鎖定相對於其他看跌期權,配件對象到數組。就在退出關鍵部分之前,put代碼將自己的易失性數組字段「ar」重新分配給希望作爲消息的編譯器和熱點編譯器創建相對於使用易失性數組引用來查找哈希值的gets的fence。

這將工作只要編譯器不NOP的「AR = AR」分配:

private volatile Object[] ar; 

public Object get (Object key) 
{ 
    Object[] ar = this.ar; 
    // get the value from the correct hash slot 
} 

public synchronized Object put (Object key, Object val) { 
{ 
    ... stuff a new object into the correct hash slot 

    ar = ar;    // will the compiler truly compile this statement with 
         // normal volatile fencing relative to the get function?? 

    ... if a race condition causes a value to already be mapped, return and use that 
    ... rather than the one we created and passed to put (different than normal put 
    ... contract) 
} 

回答

2

揮發性寫不能被優化掉,所以是的,你會得到保證內存這裏。而且,由於從數組中讀取一個值(至少在概念上)意味着你讀取數組的volatile變量,所以你應該得到一個保證volatile的讀取。

所以,雖然這應該可行 - 如果您使用Hotspot,通常的方法是使用sun.misc.Unsafe - 您可以查看Java5中向上併發的集合,該模式經常足以證明該模式。 (是的,我們都期待未來能夠獲得揮發性元素的陣列 - afaik Doug Lea和Co正在爲此制定規範,但不知道它們有多遠。)

雖然問題是爲什麼你自己實現這一點 - 有Cliff的非阻塞hashmap,它具有一些非常強的正確性保證(afaik他們用CHESS檢查了一個,很多人都查看了底層狀態機),並且與JDK中的ConcurrentHashMap相比,性能出色。

而且肯定比具有同步put操作速度更快。