2010-12-09 6 views
4

제 생각에는 동기화되지 않은 비 정적 메서드 내에서 호출되는 경우 static 메서드를 synchronized로 설정해야합니까?동기화 된 비 정적 메서드 내에서 호출되는 경우 정적 메서드를 동기화 된 것으로 만들어야합니까?

class Test 
{ 

     public static void m2() 
     { 


     } 

     public synchronized void m1() 
     { 

      Test.m2(); 
      ---- 
      ---- 
     } 

위의 경우 경쟁 조건을 피하기 위해 m2를 동기화 된 상태로 유지해야합니다. 그렇지 않으면 그대로 유지해야합니다.

답변

7

정적 방법이 무엇을하는지에 따라 다릅니다. 전혀 동기화가 필요합니까? 공유 가능한 상태에 액세스하고 있습니까? (- I가 잠 객체와 개인 정적 최종 변수를 만들 것 내가 synchronized 수정과, 그래서 그냥하지 않을 것이지만.)

그래서, 당신은 아마 동기화 할 필요 할 경우

인스턴스 메소드가 동기화되었다는 사실은 두 스레드가 동일한 대상 객체를 가진 을 실행하지 않음을 의미합니다. - 두 스레드가 모두 m1대상 객체와 함께 실행될 수 있으므로 m2은 동시에 두 번 호출 될 수 있습니다. . 그것이 문제인지의 여부는 그것이 무엇을하는지에 달려 있습니다. 공유 상태를 사용하지 않는 경우 (예 : 실제로 매개 변수를 기반으로 무언가를 계산하는 경우) 전혀 동기화 할 필요가 없습니다.

는 일반적으로 정적 메서드는 스레드 안전 인스턴스 메소드보다하는 것이 더 중요 말하기 : 나는 일반적으로 은 유형 자체 스레드 안전을, 대신 각각 동시성을 관리하기 위해 몇 가지 클래스를 사용하지 마십시오 스레드는 가능한 한 멀리있는 별도의 객체 세트를 사용합니다.

+1

마지막 단락에 약간의 문제가 있습니다. 정적에서 참조 할 수있는 코드 변경 객체는 일반적으로 수행되지 않아야하지만 스레드로부터 안전해야합니다. 거의 모든 정적 메서드는 정적을 변경하면 안되며 스레드로부터 안전 할 필요는 없습니다. 예를 들어'Collections.sort'를 스레드로부터 안전하게 만들지는 않을 것입니다. –

+0

@Tom : Collections.sort *는 다른 스레드에서 관찰되는 컬렉션을 전달하지 않는다고 가정하면 자동으로 스레드로부터 안전하다고 말할 수 있습니다. 정적 메서드가 전역 상태를 변경하지 않으면 스레드로 넘겨지는 것과 마찬가지로 스레드로부터 안전합니다. 만약 * 전역 상태를 돌연변이 (또는 잠재적으로 그냥 관찰)한다면, 스레드 안전을 위해 필요한 모든 잠금을 적용해야합니다. –

+1

'static '메소드를 언급하는 것이 더 취약합니다. – fastcodejava

0

}은 일반적으로는 static 방법을 동기화 유용 할 수있다. 예를 들어,이 경우 :

private static final List<Object> GLOBAL_STATE = new ArrayList<Object>(); 

public static synchronized void add(Object foo) { 
    GLOBAL_STATE.add(foo); 
} 

그러나이 경우에는 다른 동기화 된 메소드에서 메소드를 호출합니다. 따라서 동기화 할 필요가 없습니다. 그러나 귀하의 예에서는 static 방법 public을 작성합니다. 이것이 의도 된 것이라면 synchronized으로 만드십시오.

2

m2을 동기화해야합니다. 그렇지 않으면 누군가가 그 메소드를 동시에 호출 할 수 있습니다. 나는 m2이 동기화되는 것으로 간주 될 것이라고 가정하고 그렇지 않은 경우에는 논점입니다.

관련 문제