锁定机制 - 每个方法都运行一个队列,用于跟踪该方法正在处理的进程内密钥。
private final static Object LOCK = new Object();
private final static Set<String> busy1Records = new HashSet<String>();
private final static Set<String> busy2Records = new HashSet<String>();
public void waitToWorkOn(int i, String key) {
synchronized(LOCK) {
switch(i) {
case 1 : while (busy1Records.contains(key)) {
LOCK.wait(); //go to sleep
}
busy1Records.add(key);
break;
case 2 : while (busy2Records.contains(key)) {
LOCK.wait(); //go to sleep
}
busy2Records.add(key);
break;
}//end switch
} // end sychronized
}
public void doneWith(int i, String key) {
synchronized(LOCK) {
switch(i) {
case 1:
busy1Records.remove(key);
LOCK.notifyAll();
break;
case 2:
busy2Records.remove(key);
LOCK.notifyAll();
break;
}
要使用这些 Sets ,该类中有这些方法。
private void method1(String key) {
try {
waitToWorkOn(1,key);
// Do stuffs here for key
}catch(Exception e) {..}
finally {
doneWith(1,key);
}
}
private void method2(String key) {
try {
waitToWorkOn(2,key);
// Do stuffs here for key
}catch(Exception e) {..}
finally {
doneWith(2,key);
}
}
考虑有3个线程[每个线程都在这个类的一个新实例上工作]
T1 - key = X
T2 - key = X
T3 - key = Z
因此,当 T1 在 method1 中时,它会获取 LOCK 并将 key 添加到其 queue 中用于 method1 并释放 LOCK。但是它还没有调用 doneWith 方法,然后另一个线程 T2 尝试插入相同的实体 X。所以它在 waitToWorkON 中获取 LOCK 并且因为它发现 X 已经在 Queue1 中,所以它必须在里面等待。然后一个线程 T3 来了,它必须在独立于 X 的第三个实体 Z 上调用方法 1。但是它无法获取 LOCK,因为 T2 正在等待并持有 LOCK。
如何让 T3 继续执行 Z 的方法 1 而无需等待 T2 在 X 上等待?T1 仍未从 Queue 中释放 X。