2012-01-15 25 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操作速度更快。