3

나는 SO가시성 차이가 읽고 휘발성

Difference between synchronization of field reads and volatile

여기

질문자로부터 다음과 같은 기사를 읽고 보장하기 위해

동기화의 요점은

을 씁니다 의 값 이 스레드가 읽는 acct.balance는 최신 값이며 acct.balance에있는 객체 필드에 쓰기를 대기중인 도 모두입니다.3210은 주 메모리에 기록됩니다.

가장 인기있는 답 :

당신은 정확합니다.

public class VolatileTest { 

    static/* volatile */boolean done = false; 

    public VolatileTest() { 
     synchronized (this) { 

     } 

    } 

    public static void main(String[] args) throws Exception { 
     Runnable waiter = new Runnable() { 
      public void run() { 
       while (!done) 
        ; 
       System.out.println("Exited loop"); 

      } 
     }; 
     new Thread(waiter).start(); 
     Thread.sleep(100); // wait for JIT compilation 
     synchronized (VolatileTest.class) { 
      done = true; 
     } 
     System.out.println("done is true "); 
    } 

} 

내 PC에이 프로그램이 종료되지 않습니다

이 코드를 연구하십시오.

따라서 나는 휘발성 변수를 변경하면 내가 사방 미결제에 대한 또 다른 스레드 에 실제 값을 볼 수

  1. 생각!
  2. I는 "A"는 I는

는 I 맞죠 (다른 스레드에서 예) 모니터 "A"에서만 동기 부분의 실제 값을 참조 할 모니터 동기 부분의 변수를 변경하는 경우? 휘발성 쓰기 이 발생-전에 때문에 기록 된 값이 변수에서 읽을 수 있습니다

+0

"메인 메모리"라는 용어는 여기에 느슨한 용어입니다. 그것은 단지 일관된 관점을 의미합니다. L2 캐시는 이러한 일이 일어나도록하기 위해 서로 대화를하기 때문에 메인 메모리는 물론 L3 캐시에 변경 사항이 없을 수도 있습니다. –

+0

@ Peter Lawrey 나는 CPU에 대해 충분한 지식이 없다. 나는 아무 것도 이해하지 못했습니다 – gstackoverflow

+0

캐시가 동기화 상태를 유지하는 방법에 대해 설명합니다. http://en.wikipedia.org/wiki/Cache_coherence 일반적으로 캐시는 디자인 상 캐시가 빠를수록 주 메모리를 우회하여 서로 이야기합니다. 이것은 CPU 캐시 http://en.wikipedia.org/wiki/CPU_cache –

답변

3
  1. 예, 그건 사실입니다.
  2. 정확하게는 아닙니다. 동일한 모니터에 다른 스레드 synchronized이 업데이트 된 값을 표시한다는 보장이 있습니다. 모니터가 릴리스되기 전에 같은 모니터가 다른 스레드에 의해 획득되기 전에 발생합니다. 동일한 모니터를 획득하지 않고 다른 스레드 일 수도 있고 일 수도 있습니다. "은"당신의 제제는 너무 강한 년 :
  3. 메모리 모델은 여기에 설명되어

+0

에 대해 알아야 할 것 이상을 말해 줄 것입니다.하지만 스레드는 결국 모니터 없이도 업데이트 된 값을 보게 될 것입니다. 이 경우 메모리가 일정 시간 동안 일관성이 없더라도 잠시 후 루프가 뒤집힌 부울을 감지하면 안됩니까? – monocell

+0

@monocell 이런 일이 발생할 수 있으며 그렇게 될 수 없습니다. 우리는 이러한 일이 발생할 때 어떤 보장도없고, 전혀 일어나지 않을 것입니다. –

+0

나는 어떤 변화가 성명의 효과를 재정렬함으로써 설명 될 수 있지만, 효과의 완전한 부족이 아니라는 것을 알지 못했다. 그리고 사람들이 자바 코드 작성에 대해 저에게 돈을 지불한다고 생각하십시오. :( – monocell

2

당신이 올바른지) : 특히 Java Memory Model

, 그것은 상태 :

모니터의 잠금 해제는 해당 모니터의 모든 후속 잠금 전에 발생합니다.

휘발성 필드 (§8.3.1에 대한 쓰기.4)가 발생할 때마다 매번 그 필드가 읽히기 전에 .

이와 같이, 동일한 모니터에서 잠금 및 잠금 해제 만 원하는 방식으로 작동하고 휘발성 변수의 모든 쓰기 및 읽기도 수행합니다. 따라서 프로그램을 종료하지 않을 수도 있습니다. 모니터를 잠그지 않고 읽으면 아무 일도 일어나지 않습니다.

한 가지주의해야 할 점은 (멀티 스레드 버그가 매우 귀찮은 이유입니다.)
다른 스레드에서 변경 사항을 확인할 수 있습니다. 그렇지 않을 수도 있습니다. 대부분의 아키텍처에서는 정상적인 처리 과정에서 볼 수 있으며,로드가 많은 동안 버그가 표시되어 복제하기 어렵습니다. JVM은 발생 전 (즉, 휘발성, 동기화 된, 동일한 스레드 또는 링크의 경우와 같은 다른 경우)이 없을 때 무엇을 언제 볼 것인지를 보장하지 않지만 원활하게 실행하는 것이 가장 좋습니다.