2013-10-05 2 views
0

I가 나는 다음과 같은 방법으로 그것을 획득비교 및 ​​스왑 잘못된 값

public boolean acquireLock(Long id) { 
    if (lock.compareAndSet(0L, id)) { 
    return true ; 
    } 
    return false ; 
} 

특정 사용자 ID와 객체를 잠그는 다음 코드를

: 같은

 while(!parent.acquireLock(id)){ 
     System.out.println(lock.get()); 
     if (count++>1000000) { 
      System.out.println(id + " Trying to acquire " + lock.get()); 
      DebugHandler.createException("Error, deadlock"); 

     } 
     } 

릴리스를

public boolean releaseLock(Long id) { 

    if (lock.compareAndSet(id, 0)) { 
    System.out.println("Releasing Lock for " + id); 
    return true ; 
    } 
    else { 
    DebugHandler.createException("Lock not owned by current view. Thief"); 
    return false ; 
    } 

} 

잠금 개체를 다음과 같이 선언하십시오.

내가 함께 마무리되는 다음과 같은 이상한 행동과 교착 얻을 것을 제외하고 63,210
private volatile AtomicLong lo = new AtomicLong(0); 

:

아이디 (45)는 0

AK로, 락의 값을 취득하려고 체계적 0하지만 비교 및 ​​스왑 테스트 루프가 종료 된 후 교착 상태를 테스트하는 카운터가 다시 초기화됩니다.

아이디어가 있습니까?

+0

코드에서 잠금을 획득 할 때'this.getWorldID()'를 사용하지만 로깅에'this.id'가 사용됩니다. 이 문제를 해결하고 결과를 알려주십시오. – OldCurmudgeon

+0

정말 항상 0입니까? 때때로 0이 될 것으로 예상 할 수 있습니다. 데드 록을 의미하는 것은 아니며 스핀 록이 다른 스레드에 의해 유지된다는 것입니다. 'AtomicLong'은 원자 적이지만 블록킹되지 않습니다. – kiheru

+0

성공하면'count'를 0으로 설정하는 것을 기억하십니까? – OldCurmudgeon

답변

0

코드에 문제가 있습니다. id이 0 인 스레드를 얻으면 잠금 구성표가 손상되고 두 스레드가 동시에 잠금을 유지할 수 있습니다.

수정 : acquireLockreleaseLock 방법에 수표를 추가하여 id이 0이 아닌지 테스트합니다. 코드가 분명히 교착 상태에 들어갈 수 있는지에 관해서는

는 :

  • 정말 진짜 교착 상태가 될 수 있습니다. 예를 들어, 스레드가 id에 대한 잠금을 이미 보유하고있을 때 주어진 id에 대한 잠금을 획득하려고 시도하면이 오류가 발생할 수 있습니다. (귀하의 자물쇠는 재진입되지 않습니다.)

  • 코드가 id에 해당하는 잠금을 해제하지 못했습니다. 예 : 예외가 throw되었고 releaseLock에 대한 일반 호출을 건너 뛰었 기 때문에

+0

Id가 1로 할당되기 시작하면 ID가 0이 아닙니다. 디버깅 출력은 0이 아닌 ID 스레드가 값 0으로 잠금을 획득하려고 시도하지만 아직 CaS 테스트가 실패 함을 보여줍니다. – user1018513

+0

1) 어쨌든 '0'에 대한 수비 확인을 포함해야합니다.2) CaS 테스트가 실패하는 이유는 잠금 장치가 이미 다른 것으로 유지되고 있기 때문입니다. 나는 그것에 대해 가능한 두 가지 설명을 해 줬다. 다른 사람도있을 수 있습니다. –

관련 문제