교착 상태를 피하는 한 가지 방법은 두 개의 잠금을 획득하는 순서를 적용하여 대칭을 깨는 것입니다. 예를 들어 활을 시작할 때 스레드는 알파벳 순서대로 이름이 가장 먼저 나오는 친구에게 항상 잠금 장치를 놓아야하므로 활을 쓰는 모든 스레드는 먼저 Alphonse의 잠금 장치를 가져와야하며이어서 Gaston의 잠금 장치를 획득해야한다고 말할 수 있습니다 반대로 :
잠금이없는 옵션이 존재하는 경우 활이 이미 진행중인 경우, 신호 및 기다릴 원자 변수를 사용
public void bow(Friend bower) {
Friend lock = (this.name.compareTo(bower.name)<0)? this : bower);
synchronized (lock) {
System.out.format("%s: %s has bowed to me!%n", this.name, bower.getName());
bower.bowBack(this);
}
}
public void bowBack(Friend bower) {
Friend lock = (this.name.compareTo(bower.name)>0)? this : bower);
synchronized (lock) {
System.out.format("%s: %s has bowed back to me!%n", this.name, bower.getName());
}
}
: 교착 상태를 피할 수
private static AtomicBoolean bowing = new AtomicBoolean();
public void bow(Friend bower) {
while (!bowing.compareAndSet(false, true)) Thread.yield();
System.out.format("%s: %s has bowed to me!%n", this.name, bower.getName());
bower.bowBack(this);
bowing.set(false);
}
또 다른 방법 두 개가 아닌 한 개의 잠금을 사용하고 있습니다. 단일 잠금에 대해 경쟁하는 두 스레드는 교착 상태가 될 수 없습니다.
private static Object lock = new Object();
public void bow(Friend bower) {
synchronized (lock) {
System.out.format("%s: %s has bowed to me!%n", this.name, bower.getName());
bower.bowBack(this);
}
}
public void bowBack(Friend bower) {
synchronized (lock) {
System.out.format("%s: %s has bowed back to me!%n", this.name, bower.getName());
}
}
'잠금'동작을 구현하십시오. –
유일한 선택입니까? – hguser
모니터를 얻으려는 시간 초과에 대한 메커니즘이 필요합니다. 나는'Lock '구현체가'sun.misc.Unsafe' 로직을 사용한다고 생각한다. –