휘발성 키워드는 Java 멀티 스레딩에서 비교적 중요한 역할을합니다. 휘발성의 주요 기능은 변수를 멀티 스레딩에서 볼 수 있도록하는 것이며 Java에서 제공되는 가장 가벼운 동기화 메커니즘입니다.
시계
Java의 메모리 모델의 모든 변수 (여기서 변수는 로컬 변수가 아닌 글로벌 변수입니다. 메소드가 호출 될 때 변수가 파괴되기 때문에 스레드 안전 문제가 없습니다)는 기본 메모리에 저장됩니다. 각 스레드에는 고유 한 작업 메모리가 있습니다. 스레드가 실행될 때마다 변수의 사본은 기본 메모리에서 얻어지며, 변수의 작동은 스레드의 작업 메모리에서 수행됩니다. 다른 스레드는 작업 메모리를 공유 할 수 없으며 기본 메모리에서 변수의 사본 만 읽을 수 있습니다. 구체적으로 아래 그림에서 표현할 수 있습니다.
그러나 휘발성의 경우 (동기화/최종 수정을 사용하여, 위 규칙이 깨졌습니다. 즉, 스레드가 변수의 값을 수정할 때 다른 스레드는 변수의 변경 사항을 즉시 알 수 있습니다. 그러나 일반 변수의 경우, 스레드가 변수를 수정하면 기본 메모리에 대한 변수를 먼저 읽을 필요가 있습니다. 휘발성에 의해 수정 된 가변이 사용되는 한, 변수는 다중 스레드 환경에서 작동하는 것이 안전하다는 것을 보장합니다. 왜냐하면 모든 스레드의 작업 메모리에 볼 수 있기 때문입니다.
공개 클래스 테스트 {개인 정적 휘발성 t = 0; private static int add () {return t ++; } public static void testvolatile () {for (int i = 0; i <20; i ++) {스레드 스레드 = 새 스레드 (()-> {for (int j = 0; j <1000; j ++) {add ();}}); thread.start (); } while (ride.ActiveCount ()> 1) {Thread.yield (); } system.out.println (t); } public static void main (String [] args) {testVolatile (); }}t 값은 20,000이어야하지만 t 값이 20,000보다 미만인 상황이있을 것입니다. 당신은 이유를 추측해야합니다. 문제는 t ++에 있습니다. T ++는 원자 작동이 아닙니다. Java에서 T ++ 작동은 먼저 t 값을 얻은 다음 1을 추가 한 다음 t를 할당합니다. t 값을 얻을 때 휘발성으로 수정되므로 스레드의 최신 값을 얻을 수 있습니다. 그러나 1을 추가하면 보장 할 수 없습니다. 다른 스레드가 이미 추가되었을 가능성이 있습니다.
그렇다면 휘발성을 사용하기에 가장 적합한 시나리오는 무엇입니까?
* 변수 작동에서 현재 값에 의존하지 않습니다.
* 변수는 다른 상태 변수와 함께 불변의 제약에 참여할 필요가 없습니다.
중국어로 번역 된 것은 멀티 스레드로 읽고 쓰는 변수의 경우 휘발성을 사용하여 수정할 수 있음을 의미합니다. 이런 식으로 읽기 작업에 잠금/동기화 된 작업을 사용해서는 안됩니다. 직접 읽기는 변수가 보이기 때문입니다.