根据价值锁定/解锁?

gpa*_*gpa -1 java multithreading synchronization locking thread-safety

我有一个方法,通过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();
       }
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*you 7

解决方案可能是基于哈希码实现分段锁定,类似于如何在以下方面实现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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 不要忘记 hashCode 可以返回负值。此外,上面的代码没有提供良好的分布。更安全的方法是:locks[Math.abs(id.hashCode()) % concurrencyLevel] (2认同)