Java 基于值锁定/解锁?

Java 基于值锁定/解锁?,java,multithreading,synchronization,thread-safety,locking,Java,Multithreading,Synchronization,Thread Safety,Locking,我有一个由3个并发线程在对象实例上调用的方法。我感兴趣的锁基于值而不是对象。例如,如果两个线程T1、T2正在处理RecordID=123,T3正在处理RecordID=456。该方法应仅锁定T2,T3应继续执行 目前,我正在使用Lock,但如果T1得到Lock,它将同时锁定T2和T3 public void doSomething(String id){ try { lock.lock(); MyRecord r = find(id); ..

我有一个由3个并发线程在对象实例上调用的方法。我感兴趣的锁基于值而不是对象。例如,如果两个线程T1、T2正在处理RecordID=123,T3正在处理RecordID=456。该方法应仅锁定T2,T3应继续执行

目前,我正在使用Lock,但如果T1得到Lock,它将同时锁定T2和T3

public void doSomething(String id){
      try {
       lock.lock();
       MyRecord r = find(id);
       ...
       ....
       } finally{
         lock.unlock();
       }
}

解决方案可以是基于哈希代码实现分段锁定,类似于ConcurrentHashMap中的分段锁定:


相同的id值始终具有相同的哈希代码,因此它们将使用池中的相同锁

解决方案可以是基于哈希代码实现分段锁定,类似于ConcurrentHashMap中的分段锁定:


相同的id值始终具有相同的哈希代码,因此它们将使用池中的相同锁

或者:@VictorSorokin的解决方案非常有效。。谢谢我也会发布我的问题的解决方案。或者:@VictorSorokin的解决方案非常有效。。谢谢我也会发布我的问题的解决方案。所以1@bayou.io当然可以,但是要小心。一个通用锁可能会占用较长的时间,因此最好尽可能精细地设置。@bayou.io的想法是在执行之前初始化所有锁,因此,从数组中获取锁时不会出现竞争条件—它始终存在,并且每个哈希代码余数都有一个竞争条件。不要忘记哈希代码可能返回负值。此外,上面的代码没有提供良好的分发。更安全的方法是:将[Math.absid.hashCode%concurrencyLevel]锁定为1@bayou.io当然可以,但是要小心。一个通用锁可能会占用较长的时间,因此最好尽可能精细地设置。@bayou.io的想法是在执行之前初始化所有锁,因此,从数组中获取锁时不会出现竞争条件—它始终存在,并且每个哈希代码余数都有一个竞争条件。不要忘记哈希代码可能返回负值。此外,上面的代码没有提供良好的分发。更安全的方法是:锁[Math.absid.hashCode%concurrencyLevel]
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();
    }
}