2011-03-30 4 views
9

내가 동기화 공개 방법 및 개인 방법이있는 경우 :동기화 방법

public synchronized void doSomething() { 
    doSomethingElse() 
} 

private void doSomethingElse() { 
} 

내가 private 메소드를 동기화해야합니까를?

+2

당신이 원하는 것을하고, 동시에 실행할 수 있어야하는지에 따라 다릅니다. –

답변

1

동기화 된 메서드 (또는 synchronized 블록 내에서 호출 된 메서드)는 동기화 된 상태로 실행됩니다. 개인 메서드가 동기화 된 메서드에서만 호출되는 경우 별도로 동기화 할 필요가 없습니다.

4

아니오 :doSomethingElse()이라는 유일한 방법은 IS 동기화 된 다른 방법입니다.

가능 가능 :doSomethingElse()을 다른 방식으로 호출하면 동기화되지 않은 방법을 통해 동시 액세스로부터 보호해야합니다.

0

코드 블록을 동기화하는 경우 동일한 스레드에서 코드 블록 내에서 호출 된 항목은 여전히 ​​초기 잠금을 유지합니다. 그래서 doSomethingElsedoSomething에서 호출 될 때 여전히 동기화 된 블록의 일부입니다.

당신이 한 경우

public synchronized void doSomething() { 
    new Thread() { 
    public void run() { 
     doSomethingElse(); 
    } 
    }.start(); 
} 
private void doSomethingElse() { 
} 

그런 doSomethingElsedoSomething 인수 한 잠금을하지.

또한 동시성 정책의 구현 세부 사항을 노출하므로 동기화 된 메소드를 피하십시오. 동기 (이)/동기화 방법에이 질문을 참조하십시오 : doSomethingElse가 동기화되어야합니다 Avoid synchronized(this) in Java?

경우 관계없이 doSomething에서 호출 여부, 그것은 doSomethingElse를 동기화 할 해치지 않을 것 동기화 잠금대로 다시 참가자 (즉, thread가 이미 객체에 락을 가지고있는 경우, 락을 다시 얻을 수있다).

0

개인적으로 필자는 동기화 된 방법이 마음에 들지 않습니다. 어떤 종류의 잠금 장치와도 동기화하는 것을 선호합니다.

private final Object lock = new Object(); 

public void doSomething() { 
    synchronized(lock) { 
    // Do some safely 
    doSomethingElse(); 
    } 
    // Do some work un-safely 
} 

private void doSomethingElse() { 
    // Do some work safely because still in lock above 
    // ... 
} 
5

당신이하는 일에 따라 다릅니다. doSomethingElse()에 대한 시리얼 액세스를 보장해야합니까?

그렇다면 doSomethingElse()을 호출하는 것은 doSomething()이며, 아니오, 동기화 할 필요가 없습니다. 그러나 다른 방법으로 doSomethingElse()을 호출 할 수 있다면 그렇습니다. 또한 동기화해야합니다.

13

그것은 따라 달라

  • doSomethingElse 경우에 당신이 synchronized 필요하지 않습니다, 동시에 호출하는 것이 안전합니다.그렇지 않은 경우
  • , 그 대답은이 호출되는 위치에 따라 달라집니다이 유일한 synchronized 방법에서 호출하면
    • , 그것은 synchronized를해야 (그러나 같은 의지로 표시하지 않습니다 해를 끼치 지 마라);
    • synchronized이 아닌 메서드에서 호출 할 수있는 경우 이어야합니다. synchronized이어야합니다. 괜찮 무슨 짓을했는지, 내 의견으로는, 동기화가 가능한 최저 단위에서 수행해야하지만
0

. 어떤 실제 개인 기능을 동기화하는 것이 좋습니다 것입니다. 현재 클래스의 다른 함수가 개별 함수를 독립적으로 호출하지 않는다고 가정합니다. 앞으로는 그렇지 않을 수도 있습니다.

2

이것은 @GuardedBy 주석의 의도입니다. 당신이 메서드를 호출 할 때 잠금 반드시 개최 할 것으로 예상되는 경우, 그와 함께 주석을 달고 예에서 잠금 (의 이름은은 다음과 같습니다

@GuardedBy("this") private void doSomethingElse() {…} 

그런 다음 당신은 불변이 사실임을 확인하실 수 있습니다 FindBugs와.

당신은 또한 그것의 스레드 안전 또는 부족을 설명하기위한 other net.jcip.annotations을 사용하고 FindBugs도 이러한 가정을 검증 할 수 있습니다. 물론, the book뿐만 아니라 플러그인이 필요합니다.

0

심지어 코드가 작동하는 것처럼 개인 메서드가 동기화되지 않은 경우 올바르게 개인화 된 방법을 동기화하기 위해 유지 관리 가능성 관점에서 신중하게 보일 것입니다.

본질 잠금은 재 입력이므로 개인 키워드 메서드에 synchronized 키워드를 추가해도 아무런 해가 없습니다.

개인 메서드에 코드를두면 다른 메서드에서 코드를 호출 할 수 있으므로 나중에 동기화 할 필요가없는 다른 메서드에서 이후에 호출 할 경우 개인 메서드를 동기화 할 수 있습니다.

관련 문제