2014-01-06 2 views
2

현재 The Well-Grounded Java Developer 책에서 동시성에 관한 섹션을 읽었으며 블록 동시성을 보여주는이 코드 샘플은 교착 상태에 있어야하지만 지금까지 볼 수는 없습니다. 여기에 코드입니다 : 나는 그것을 실행하면이 예에서 교착 상태는 어디에 있습니까?

public class MicroBlogNode implements SimpleMicroBlogNode { 

    private final String ident; 

    public MicroBlogNode(String ident_){ 
     ident = ident_; 
    } 

    public String getIdent(){ 
     return ident; 
    } 

    public static Update getUpdate(String _name){ 
     return new Update(_name); 
    } 

    public synchronized void propagateUpdate(Update upd_, MicroBlogNode backup_){ 
     System.out.println(ident + ": received: " + upd_.getUpdateText() + " ; backup: " + backup_.getIdent()); 
     backup_.confirmUpdate(this, upd_); 
    } 

    public synchronized void confirmUpdate(MicroBlogNode other_, Update update_){ 
     System.out.println(ident + ": received confirm: " + update_.getUpdateText() + " from " + other_.getIdent() + "\n"); 
    } 

    public static void main(String[] args) { 
     final MicroBlogNode local = new MicroBlogNode("localhost"); 
     final MicroBlogNode other = new MicroBlogNode("remotehost"); 
     final Update first = getUpdate("1"); 
     final Update second = getUpdate("2"); 

     new Thread(new Runnable() { 
      public void run() { 
       local.propagateUpdate(first, other); 
      } 
     }).start(); 

     new Thread(new Runnable() { 
      public void run() { 
       other.propagateUpdate(second, local); 
      } 
     }).start(); 
    } 
} 

내가 얻을 다음과 같은 출력 :

localhost: received: 1 ; backup: remotehost 
remotehost: received confirm: 1 from localhost 

remotehost: received: 2 ; backup: localhost 
localhost: received confirm: 2 from remotehost 

이 책은 코드를 실행하는 경우, 당신은 일반적으로 교착 상태-모두의 예를 볼 수 있다고 말한다 스레드가 업데이트 수신을보고하지만 어느 쪽도 백업 스레드 인 에 대한 업데이트 수신을 확인하지 못합니다. 그 이유는 확인 메소드가 진행되기 전에 보유하고있는 잠금을 해제하기 위해 각 스레드가 다른 스레드를 요구하기 때문입니다.

내가 알 수있는 한,이 경우가 아니라는 것을 알 수 있습니다. 각 스레드는 그들이 백업 스레드 인 업데이트를 수신하는 것을 확인합니다.

미리 감사드립니다.

+3

이것이 책의 예입니까? 'Update' 클래스를 보여주세요. –

+0

'getUpdateText' 메소드는 어디에 있습니까? – wheaties

답변

1

localother이 동일한 호출을 시도 할 때 confirmUpdate에 스레드 작업을 호출하면 교착 상태가 발생합니다. 따라서, 교착 propagateUpdate

  • Local 시도를 호출
  • '기타'잠금 자체 (Synchronized Member Function in Java 참조)

    1. Local 잠금 자체 그것 때문에 synchronized 인 선언에 propagateUpdate를 호출함으로써 동작의 순서에 따라 일어날 Other의 자물쇠를 획득하여 confirmUpdate을 호출 할 수 있지만 Other은 이미 다른 스레드에서 잠겨 있기 때문에 그럴 수 없습니다.
    2. Other 동일한 작업을 시도하지만 동일한 이유로 실패합니다.

    실제로 작동하는 경우 이는 매우 빠르게 진행되고 있기 때문일 수 있습니다. 몇 번 더 실행하십시오. 스레드 문제는 그들이 작동하기를 원할 때 결코 작동하지 않습니다.

  • +0

    여러 번 다시 실행하여 코드를 교착 상태로 만들었습니다. – user283188

    +0

    @ user283188 좋아요! 이것은 하나의 스레드가 다른 스레드가 현재 사용하고 있지만 포기할 방법이없는 자원을 사용하려고 시도하는 고전적인 "기아 (starvation)"문제입니다. – wheaties

    2

    타이밍과 비슷합니다. 원격 호스트 (다른) 스레드가 시작되기 전에 localhost 스레드가 완료되었음을 사용자가 출력하고 있습니다. 교착 상태를 강제해야 System.out에

    public synchronized void propagateUpdate(Update upd_, MicroBlogNode backup_){ 
        System.out.println(ident + ": received: " + upd_.getUpdateText() + " ; backup: " + backup_.getIdent()); 
        Thread.sleep(1000); 
        backup_.confirmUpdate(this, upd_); 
    } 
    

    이 후 propogateUpdate 방법에서 (1000) Thread.sleep를 바꾸어

    보십시오.

    관련 문제