2012-11-14 2 views
4

더티 값의 문제없이 다른 스레드에서 읽고 쓸 수있는 플래그를 갖고 싶습니다. 정전기를 휘발성으로 만드는 것으로 충분합니까? 이 같은 조치가 필요한 경우Java : 정적 가변 변수를 사용할 올바른 방법이 있습니까?

static volatile boolean flag; 
+2

충분하지 않 은지 확실하지 않지만 ['AtomicBoolean'] (http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic)을 사용하는 것이 좋습니다. /AtomicBoolean.html)를 사용하십시오. –

+0

가능할 때마다 고정 된 가변 필드를 피할 것입니다. 대신 플래그를 지정하려는 스레드에 전달되는 AtomicBoolean을 사용합니다. –

답변

5

아니,이 충분하지 않습니다 :

volatile int v = 0; 

Thread 1: 
v++; 

Thread 2: 
v--; 

가 이상적으로 당신이 원하는 V = 0 위의 코드를 실행하지만,이 정말 무슨 일이 일어나고있는 경우 (A 복합 액션) :

Thread 1: 
r1 = v; 
r2 = r1 + 1; 
v = r2; 

Thread 2: 
r3 = v; 
r4 = r3 - 1; 
v = r4; 

두 스레드는 각각 1과 -1 값을 제공합니다. 출처 : Volatile Does Not Mean Atomic!

mulithreaded 시나리오에서 일관된 결과를 보장해야한다면 @ Eng.Fouad가 지적한대로 Java의 Atomic 클래스를 사용해야합니다.

boolean의 경우에도 compare-and-set은 volatile을 사용하는 것보다 AtomicBoolean 클래스에서 유용합니다.

+0

예, 데이터를 읽고 calucalte하고 저장하는 작업입니다. 하지만 부울 vars로 읽기 \ 쓰기 작업에만 사용하는 것이 맞습니까? –

+0

나는 그것을 얻지 않았다. 당신은 r/w 작전에 사용할 휘발성 올바른 질문입니까? (방금 대답했습니다) – zengr

+0

아니요, 우리는 정적 휘발성 플래그가 있음을 의미합니다. 그런 다음 나는 그것을 거짓으로 표시하고, 다른 스레드는 그것을 읽고, 다른 스레드는 그것을 사실로 표시합니다. 이 경우 더러운 값을 얻게 되나요? –

3

유혹이지만 그처럼 코드는 피하십시오.

간단한 시나리오에서 boolean은 수학 연산을 허용하지 않으므로 (값만 할당 할 수 있음)이 방법이 효과가있는 것 같습니다. 그러나 단순한 경우는 거의 없습니다. 결국, 당신은 필요합니다

if(flag) { 
    flag = false; 
} 

이 코드는 때로는 중단됩니다. 따라서 다른 답변에서 제안한 것처럼 java.util.concurrent.Atomic * 클래스를 사용해야합니다.

관련 문제