2013-09-27 1 views
1

오라클에서 Java Concurrency Tutorial을 읽습니다.자바에서 DeadLock을 해결하는 대안

public synchronized void bow(Friend bower) { 
     System.out.format("%s: %s" + " has bowed to me!%n", this.name, bower.getName()); 
     bower.bowBack(this); 
    } 

    public synchronized void bowBack(Friend bower) { 
     System.out.format("%s: %s" + " has bowed back to me!%n", this.name, bower.getName()); 
    } 

그리고 가이드가 LockObject로 전환 될 때 그리고,이 Lock Object 의한 교착 상태를 처리하는 솔루션을 제공

는 그리고 DeadLock

핵심 코드의 일례가있다.

이제 Lock 개체를 사용하지 않고 교착 상태를 피할 수있는 대체 방법이 있는지 궁금합니다.

+1

'잠금'동작을 구현하십시오. –

+0

유일한 선택입니까? – hguser

+0

모니터를 얻으려는 시간 초과에 대한 메커니즘이 필요합니다. 나는'Lock '구현체가'sun.misc.Unsafe' 로직을 사용한다고 생각한다. –

답변

3

교착 상태를 피하는 한 가지 방법은 두 개의 잠금을 획득하는 순서를 적용하여 대칭을 깨는 것입니다. 예를 들어 활을 시작할 때 스레드는 알파벳 순서대로 이름이 가장 먼저 나오는 친구에게 항상 잠금 장치를 놓아야하므로 활을 쓰는 모든 스레드는 먼저 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()); 
     } 
    } 
+0

정말 훌륭합니다! 나는'synchronized'가 이런 식으로 사용될 수 있다고 생각한 적이 없다. BTW, java의'thread, concurrency'에 관한 튜토리얼을 추천 할 수 있습니까? 이 글에서 언급 한 튜토리얼은 다소 높은 수준이므로 좀 더 자세한 가이드가 필요합니다. :) – hguser