2016-07-24 3 views
0

간단히 말해,이 동작이 변경되는지 궁금합니다. someMethod()를 호출하면 목록 개체 대신 전체 개체가 잠기기 때문에 예라고 가정합니다. 그러나 나는 아직도이 동기화 작업에 익숙하지 않아 좀 더 교육 된 피드백을 원합니다.동기화 된 블록에서이 동기화 된 메서드를 호출해도 괜찮습니까?

사전이 :

public void run() { 
    int i = 0; 

    while (!end) { 
     synchronized (list) { 
      while (list.size() == i) { 
       try { 
        list.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
} 

애프터 :

public void run() { 
    int i = 0; 

    while (!end) { 
     synchronized (list) { 
      while (list.size() == i) { 
       someMethod(); 
      } 
     } 
    } 
} 

public synchronized void someMethod() { 
    try { 
     list.wait(); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

답변

2

당신이 올바른지 - someMethod() 실제로이에 호출되는 인스턴스에 동기화 될 때, 새로운 코드가 다른 의미를 가지고있다 (따라서 동기화는 list에있는 것과 완전히 관련이 없습니다. 그러나 list의 모니터가 보류 중일 때 someMethod()에 대한 호출이 수행되므로 에 대한 호출은 list에 대해 "동등한 스레드 안전"입니다.

한편, 복수 스레드가 동시에 someMethod()을 호출 할 가능성을 소개했습니다. 또한 객체 자체에 대한 추가 동기화로 인해 다른 스레드와의 교착 상태가 발생할 가능성이 있음을 알았습니다. 내가 대신을 추천 할 것입니다 :

public void someMethod() { 
    synchronized (list) { 
     try { 
      list.wait(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

를이 방법은 개별 사용 및 run()를 통해 호출되는 모두 지금은 안전합니다 - 당신이 이미에 동기화 한 객체에 동기화하는 것이 안전합니다 있습니다; 스레드가 스스로 차단되지 않습니다.

+0

감사합니다. 감사합니다. – Badger

2

syncronized을 사용하면 개체를 '고정'하지 않습니다. 특정 개체에서 을 동기화하는 모든 사람의 액세스가 잠금 장치로 '규제'되는지 확인하면됩니다.

동기화 된 메서드가 this에서 동기화 중입니다.

이 코드는 '아무튼 : 일부 개체 listsyncronized 블록을 입력하면 먼저


어떤 사물을 문제없이 syncronized 메서드를 호출 할 수 있습니다 의미

에 대해 생각한다 이미이 this의 "잠금"이 때문에

public void foo() { 
    synchronized (this) { 
     someMethod(); 
    } 
} 

public synchronized void someMethod() { 
    // ... 
} 

: t은 교착 상태 발생 그러나 이것 :

다른 스레드와 교착 상태가 발생할 수 있습니다! synchronized 섹션에 다른 synchronized 섹션을 입력하면 매우 신중해야합니다.

관련 문제