2017-01-19 5 views
1

교착 상태는 하나 이상의 스레드가 잠금 가능 자원을 통해 루프를 생성 할 가능성에 의해 생성 된 주기적 종속성이있는 경우에만 가능합니다.항상 Java Lock에서 tryLock을 사용하여 데드락을 막을 수 있습니까?

하나의 옵션은 신중한 정적 분석 또는 잠금 획득을위한 디자인 패턴을 통해 이러한 순환을 피하는 것입니다.

그러나 잠금 인터페이스에서 tryLock을 사용하여 교착 상태를 방지 할 수 있습니까? tryLock은 원자 적으로 잠금을 시도합니다. 성공하면 true를 반환하고 잠금 상태이면 false를 반환하여 코드를 건너 뛸 수 있습니다.

int sharedStateA = 0; 
int sharedStateB = 0; 
Lock lockA = new ReentrantLock(); 
Lock lockB = new ReentrantLock(); 

// possible deadlock safe solution 

// executed by thread 1 
void deadLockSafeUpdateAthenB(){ 
    try { 
     if (lockA.tryLock()){ 
      sharedStateA = sharedStateA + 1; 

      try { 
       if (lockB.tryLock()){ 
        sharedStateB = sharedStateB + 1; 
       } 
      } finally { 
       lockB.unlock(); 
      } 
     } 
    } finally { 
     lockA.unlock(); 
    } 
} 

// executed by thread 2 
void deadLockSafeUpdateBthenA(){ 
    try { 
     if (lockB.tryLock()){ 
      sharedStateB = sharedStateB + 1; 

      try { 
       if (lockA.tryLock()){ 
        sharedStateA = sharedStateA + 1; 
       } 
      } finally { 
       lockA.unlock(); 
      } 
     } 
    } finally { 
     lockB.unlock(); 
    } 
} 
+1

교착 상태까지는 안전해야하지만 결과 동작이 올바른지 확인해야합니다. – shmosel

+0

자물쇠를 인수하지 않으면 상태 업데이트가 발생하지 않을 수도 있다는 것을 알고 있습니까? 그런 접근법이 유용 할 때 나는 거의 상상하지 못한다. – Anton

답변

1

Lock.tryLock()와 귀하의 코드는 안전 교착 상태이지만 다른 방법을 사용하려고한다

public boolean tryLock(long timeout, 
       TimeUnit unit) 

당신의 스레드가 짧은 실행 시간이있는 경우. - tryLock(0,TimeUnit.SECONDS)tryLock()이이를 준수하지 않는 동안 대기 잠금 대기열이 적용되는 공정성 정책을 준수하기 때문에 Lock.tryLock()보다 좋습니다.

비록 정적 분석이 코드가 교착 상태에 빠지기는하지만, 교착 상태가 발생하기 쉬운 코드가 실제로 모든 불운 한 타이밍 게임 이후 실제로 교착 상태를 발생시킬 필요는 없다고 알려주는 경우 tryLock()을 사용하는 목표는 기능적으로 동일한 것을 생성해야합니다. 교착 상태가 발생하지 않는다고 가정하고 교착 상태가 발생하기 쉬운 코드와 같은 프로그램.

한 가지 문제를 해결하면 다른 문제가 발생하지 않아야합니다. 일부 재수없는 타이밍에서 하나의 스레드가 전혀 실행되지 않을 수도 있으므로 코드 잠금에서 trylock 대신 tinyock을 사용하는 것이 좋습니다. 취득은 그 순서대로 이루어져야합니다.

희망이 있습니다!