자바에서는 Long과 Double의 8바이트 64비트 변수를 제외하고는 다른 기본 변수들이 원자입니다.
Java 스토리지 모델은 get과 store 모두 원자적 연산을 요구하지만, 비휘발성 롱 및 더블 변수의 경우 JVM은 64비트 읽기 또는 쓰기를 두 개의 32비트 연산으로 나눌 수 있게 합니다.
읽기와 쓰기가 서로 다른 스레드에서 이루어지면, 비휘발성 타입의 롱을 읽으면 한 값은 32비트 정도는 높게, 다른 값은 32비트 정도 낮게 나올 수 있습니다.
그래서 만료된 데이터에 신경 쓰지 않더라도, 멀티스레드 프로그램에서 공유되고 변경 가능한 롱 및 더블 변수를 사용하는 것은 불안정하거나 잠금으로 보호되지 않는 한 안전하지 않을 수 있습니다.
원자 연산에 대해 말하자면, 읽기와 쓰기는 원자적이라는 의미로, 예를 들어 i=5; 이건 원자력 작전이야.
하지만 두 원자의 연산이 함께 수행되고, 반드시 원자적인 연산이 아니라면, 예를 들어 먼저 읽고 쓰는 경우, 변수가 읽기 후에 수정되었을 가능성이 있습니다.
i++는 그런 연산으로, 먼저 읽고 쓰기 때문에 정수 변수는 원자(atomic)이지 i++가 원자 연산이라는 뜻은 아닙니다.
for(int i=0; i<10000; i++){System.out.print(i)}
결국 1만 장을 인쇄하지 않고 약 8천에서 9천 장 정도 인쇄할 것입니다.
하지만 멀티스레딩의 경우, 정수 변수가 원자라도 스레드 안전 문제가 발생할 수 있는데, 이는 스레드 가시성 문제이므로 휘발성 명단을 추가해야 합니다.
이 수정자는 매번 메모리에서 읽히는 강제 변수이며 레지스터에 저장되지 않습니다. |