JSR133 중volatile 키워드 이해
4645 단어 thread.netcacheBlogperformance
volatile
guaranteed only that reads and writes of volatile
fields would be made directly to main memory, instead of to registers or the local processor cache, and that actions on volatile variables on behalf of a thread are performed in the order that the thread requested. In other words, this means that the old memory model made promises only about the visibility of the variable being read or written, and no promises about the visibility of writes to other variables. While this was easier to implement efficiently, it turned out to be less useful than initially thought. While reads and writes of volatile variables could not be reordered with reads and writes of other volatile variables, they could still be reordered with reads and writes of nonvolatile variables. In Part 1 , you learned how the code in Listing 1 was not sufficient (under the old memory model) to guarantee that the correct value for
configOptions
and all the variables reachable indirectly through configOptions
(such as the elements of the Map
) would be visible to thread B, because the initialization of configOptions
could have been reordered with the initialization of the volatile initialized
variable. Map configOptions;
char[] configText;
volatile boolean initialized = false;
//In Thread A
configOptions = new HashMap();
configText = readConfigFile(fileName);
processConfigOptions(configText, configOptions);
initialized = true;
//In Thread B
while (!initialized)
sleep();
//use configOptions
Unfortunately, this situation is a common use case for volatile -- using a volatile field as a "guard"to indicate that a set of shared variables had been initialized. The JSR 133 Expert Group decided that it would be more sensible for volatile reads and writes not to be reorderable with any other memory operations -- to support precisely this and other similar use cases. Under the new memory model, when thread A writes to a volatile variable V, and thread B reads from V, any variable values that were visible to A at the time that V was written are guaranteed now to be visible to B. The result is a more useful semantics of
volatile
, at the cost of a somewhat higher performance penalty for accessing volatile fields. volatile의 의미:
1. volatil e역에 대한 읽기와 쓰기가 메인 메모리에서 직접 진행되고 루트의 로컬 메모리에 캐시되지 않도록 합니다.
2. 이전 JMM에서 volatil e역의 작업과 nonvolatil e역의 작업 사이를 다시 정렬할 수 있습니다.그러나 JSR133 이후volatile 작업과 다른 메모리 작업 사이에는 재배열을 허용하지 않는다.
3. 새로운 JMM에서 스레드 A가volatile 변수 V를 쓴 다음에 스레드 B가 V를 읽을 때 스레드 A에 대한 모든 변수 값을 B에 표시합니다
세 번째는 이상해요. 약간 Synchronized의 작용인 것 같아요.루틴 A가volatile 변수를 쓸 때 로컬 캐시에 있는non-volatile 변수를 메모리에 새로 고침하고,volatile 변수를 읽을 때 로컬 캐시에 있는non-volatile 변수를 업데이트합니까?그렇지 않으면 라인 B가 어떻게 그런 nonvolatile 변수를 볼 수 있겠는가?
이 문제에 대해 몇 가지 자료를 조회하였는데'volatile 필드의 읽기와 쓰기는 모니터에 들어오고 종료하는 것과 비슷한 메모리 일치성 효과가 있다'(http://blog.csdn.net/lovingprince/archive/2010/04/04/5450246.aspx)
volatile 변수의 읽기와 쓰기에happens-before의 편차 관계가 있습니다
A write to a volatile fieldhappens-before every subsequent read of that same volatile. 이 점은 의문이 없다.
Because the write of the volatile variable
initialized
happens after the initialization of configOptions
, the use of configOptions
happens after the read of initialized
, and the read of initialized
happens after the write to initialized
, you can conclude that the initialization of configOptions
by thread A happens before the use of configOptions
by thread B. Therefore, configOptions
and the variables reachable through it will be visible to thread B. 새 JMM에서volatile을 사용하면 위의 코드가 합리적인지 확인할 수 있습니다.다음 "<"는 happens-before의 뜻입니다.
1. "스레드 A에서 configOptions 초기화"<"스레드 A에서 initialized 변수 쓰기"
2. "스레드 B에서 initialized 변수 읽기"<"스레드 B에서 configOptions 사용"
3. “write to volatile field” < “subsequent read of that same volatile”
또한 action1
즉volatile 변수를 사용한 후non-volatile 변수의 조작 사이에도happens-before 관계가 생겼다는 것이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Exception in thread main java.lang. NoClassDefFoundError 오류 해결 방법즉,/home/hadoop/jarfile) 시스템은 Hello World 패키지 아래의class라는 클래스 파일을 실행하고 있다고 오인하여 시스템의 CLASSPATH 아래 (일반적으로 현재 디렉터리를 포함) Hell...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.