【发布时间】:2014-07-14 08:41:52
【问题描述】:
我有一个被多个线程访问的键值映射:
private final ConcurrentMap<Key, VersionValue> key_vval_map = new ConcurrentHashMap<Key, VersionValue>();
我的自定义 get() 和 put() 方法遵循典型的 check-then-act 模式。因此,同步对于保证原子性是必要的。为了避免锁定整个ConcurrentHashMap,我定义:
private final Object[] locks = new Object[10];
{
for(int i = 0; i < locks.length; i++)
locks[i] = new Object();
}
然后get() 方法运行(它调用ConcurrentHashMap 的get() 方法):
public VersionValue get(Key key)
{
final int hash = key.hashCode() & 0x7FFFFFFF;
synchronized (locks[hash % locks.length]) // I am not sure whether this synchronization is necessary.
{
VersionValue vval = this.key_vval_map.get(key);
if (vval == null)
return VersionValue.RESERVED_VERSIONVALUE; // RESERVED_VERSIONVALUE is defined elsewhere
return vval;
}
}
put() 方法运行(它调用上面的get() 方法):
public void put(Key key, VersionValue vval)
{
final int hash = key.hashCode() & 0x7FFFFFFF;
synchronized (locks[hash % locks.length]) // allowing concurrent writers
{
VersionValue current_vval = this.get(key); // call the get() method above
if (current_vval.compareTo(vval) < 0) // it is an newer VersionValue
this.key_vval_map.put(key, vval);
}
}
上面的代码有效。但是,如您所知,在多线程编程中工作远非正确。
我的问题是:
这种同步机制(尤其是
synchronized (locks[hash % locks.length]))在我的代码中是否必要且正确?
锁实现提供了比锁更广泛的锁定操作 可以使用同步的方法和语句获得。
那么在我的代码中用Lock替换synchronization可行吗?
编辑:如果您使用的是 Java-8,请不要犹豫,参考@nosid 的答案。
【问题讨论】:
标签: java multithreading synchronization locking concurrenthashmap