我有一个方法,它由3个并发线程在对象实例上调用。我感兴趣的锁是基于价值而不是对象。例如,如果两个线程(T1,T2)正在处理RecordID = 123并且T3正在处理RecordID = 456。该方法应仅锁定T2,T3应继续执行。
目前,我正在使用Lock,但如果T1被锁定,它将锁定T2和T3。
public void doSomething(String id){
try {
lock.lock();
MyRecord r = find(id);
...
....
} finally{
lock.unlock();
}
}
答案 0 :(得分:6)
解决方案可能是基于哈希码实现分段锁定,类似于ConcurrentHashMap
中的方式:
int concurrencyLevel = 1 << 8; // 256 locks
final Lock[] locks = new Lock[concurrencyLevel];
// initialize locks
void doSomething(String id) {
Lock lock = locks[id.hashCode() & (concurrencyLevel - 1)]; // select one of 256 locks
lock.lock();
try {
// do some work
} finally {
lock.release();
}
}
相同的id
值始终具有相同的哈希码,因此它们将使用池中的相同锁。