2014-07-16 4 views
1

인스턴스 변수가 있고 setter 및 getters가 있다고 가정합니다.Java 다중 스레드 게터 및 설정자

코드 1 :

Class<T> { 
    volatile T value; 

    public synchronized void set(T v) { 
     if(value==null) { 
      value=v; 
     } 

    } 

    public T get() { 
     return value; 
    } 
} 

코드 2 :

Class<T> { 
    static volatile T value; 

    public synchronized void set(T v) { 
     if(value==null) { 
      value=v; 
     } 
    } 

    public T get() { 
     return value; 
    } 
} 

나는이 두 가지 질문

1) 정적 휘발성 상태 필드 만 휘발성 상태 필드를 갖는 차이점은 무엇입니까?

2) 방금 읽기/쓰기의 개념에 대해 알게되었고 (캐시 플러시로 인해) getter를 동기화 할 필요가 없다는 것을 이해했습니다. 그러나 세터를 동기화 할 필요가 있습니까?

+3

첫 번째 질문에 대한 답변은 멀티 스레딩과 관련이 없습니다. 정적 변수는 정적 변수입니다. 변수가 휘발성인지 아닌지는 관련이 없습니다. – assylias

+0

@assylias 아니요, 이것을 고려해보십시오 :'class X implements Runnable {private static Object o; public void run() {o = new Object(); }}'. 변수가 정적이거나 그렇지 않은 경우이 경우 중요합니다. –

+2

@ Absurd-Mind 나는 static이 아무 쓸모가 없다고 말하지 않았다. 단지'static' 키워드의 의미는 비 휘발성 변수와 휘발성 변수가 동일하다고 만 말했다. – assylias

답변

0

의이 두 번째 질문부터 시작하자 :

나는 당신이 당신의 세터에 동기화 된 블록을 사용 schould 이유는 두 개의 서로 다른 작업 value을 수행하는 것이라고 생각합니다. value==null을 확인한 후 value=v을 설정합니다. 당신이 각 단계마다 자물쇠를 가지고 있지만 당신은 그들 사이에 그것을 가지고 있지 않습니다. 가능한 경우 :

Thread1: lock value -> value==null (true) -> release value 
Thread2: lock value -> value==null (true) -> release value 
Thread1: lock value -> value=v -> release value; 
Thread2: lock value -> value=v -> release value; 

그래도 여전히 경쟁 조건이 있습니다.

이제 첫 번째 질문으로 돌아가십시오. 클래스의 인스턴스에 고유 한 변수 대신 동일한 변수 T를 사용하려면 static을 사용하십시오. 코드 2에서

-2

는 다음이 가능합니다 :

Thread1: calls set(X) on instance1 
Thread1: value is null, entering inside if 
Thread2: calls set(Y) on onstance2 
Thread2: value is null, entering inside if 
Thread2: setting value = Y 
Thread1: setting value = X 

문제는 잠금이 클래스가 아닌 클래스 자체의 인스턴스에 인수된다. setget 방법을 모두 static으로 변경하면 다시 정상적으로 작동합니다.