ロック メカニズム - 各メソッドは、そのメソッドで進行中のインプロセス キーを追跡するためのキューを実行します。
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 にある場合、T1 は LOCK を取得し、method1 のキューにキーを追加して、LOCK を解放します。しかし、まだ doneWith メソッドを呼び出しておらず、別のスレッド T2 が同じエンティティ X を挿入しようとしています。そのため、waitToWorkON で LOCK を取得し、X が既に Queue1 にあることがわかったため、内部で待機する必要があります。次に、X から独立した 3 番目のエンティティ Z で method1 を呼び出さなければならないスレッド T3 が発生します。ただし、T2 が待機してロックを保持しているため、ロックを取得できません。
T2がそこでXを待っているのを待たずに、T3にZのmethod1を続行させるにはどうすればよいですか? T1 はまだ X をキューから解放していません。