프로그램은 휘발성 키워드의 기능을 테스트해야 합니다. 그러나 "Thread.sleep(1)을 Thread.sleep(1000)으로 바꾸면 원하는 효과를 얻을 수 있습니다"는 올바른 이해가 아닙니다. 우선 프로그램에는 두 개의 스레드가 있습니다. 메인 스레드(가칭 스레드 M이라고 함)와 new Thread(td)(가칭 스레드 T라고 함)입니다. volatile 关键字的功能。但是 “把 Thread.sleep(1) 换成 Thread.sleep(1000) 就能获得预期效果” 这样做理解上是不对的。 首先,程序中总共有两个线程,主线程(暂称 线程M)和 new Thread(td) (暂称 线程T)。
为了让 线程M 及时读取到 线程T 中 flag 的值,需要将 flag 使用 volatile 关键字进行修饰:
private volatile boolean flag = false;
那么每次对 flag 的修改,其他线程都立马可见。关于 volatile
Thread.sleep(1)을 작성할 때 스레드 M은 1ms 후 while(true) 루프에서 td.isFlag() 검사를 시작합니다. 그러나 메모리 가시성으로 인해 스레드 M은 스레드 T의 플래그 값을 적시에 읽을 수 없으므로 이때 무한 루프가 발생합니다. 🎜
🎜Thread.sleep(1000)을 작성할 때 M은 1000ms 후에 while(true) 루프에서 td.isFlag()를 확인하기 시작합니다. code>; 그러나 T는 200ms에서 flag 값을 true로 설정하므로 M은 td.isFlag( 1000ms 이후 )를 감지하여 true이면 첫 번째 판단은 true를 반환하고 출력을 생성하며 while(true) code> 루프에서 빠져나옵니다. 🎜
🎜스레드 M이 스레드 T의 flag 값을 적시에 읽으려면 flag를 휘발성 키워드로 수정해야 합니다. 🎜
으아아아
🎜그러면 플래그에 대한 모든 수정 사항이 즉시 다른 스레드에 표시됩니다. 휘발성 사용에 대해서는 내 블로그인 Java Multithreading (6): Use of the 휘발성 키워드 🎜를 참조하세요.
다음 3가지 코드를 참고하시면 됩니다. 첫번째는 멀티스레딩의 가시성 문제로 인해 무한루프가 발생할 수 있는 상황입니다. 두 번째는 이 문제를 해결하기 위해 synchronized를 사용하는 것입니다. synchronized解决此问题,大多数工作场景用这个好 第三个是使用volatile세 번째는 이 문제를 해결하기 위해 휘발성을 사용하는 것입니다. 실제 시나리오에서는 제한이 상대적으로 크기 때문에 주의해서 사용하세요
기대되는 효과가 무엇인지 먼저 말씀해 주셔야 겠죠? 명확하게 질문하세요
이러한 기대는 표준에 의해 뒷받침되지 않습니다. "메인 스레드를 읽기 전에 하위 스레드 쓰기가 발생합니다"를 보장하기 위해 코드에서는 아무 작업도 수행되지 않습니다.
sleep(1000)
나중에 수정 사항을 보는 것은 단지 우연일 뿐입니다. JVM이 메인 스레드가 이를 볼 때까지 더 오래 기다리거나 심지어 메인 스레드가 이를 볼 수 없도록 허용하는 경우에도 사양을 위반하지 않습니다.프로그램은
휘발성
키워드의 기능을 테스트해야 합니다. 그러나 "Thread.sleep(1)
을Thread.sleep(1000)
으로 바꾸면 원하는 효과를 얻을 수 있습니다"는 올바른 이해가 아닙니다.우선 프로그램에는 두 개의 스레드가 있습니다. 메인 스레드(가칭 스레드 M이라고 함)와
new Thread(td)
(가칭 스레드 T라고 함)입니다.volatile
关键字的功能。但是 “把Thread.sleep(1)
换成Thread.sleep(1000)
就能获得预期效果” 这样做理解上是不对的。首先,程序中总共有两个线程,主线程(暂称 线程M)和
new Thread(td)
(暂称 线程T)。当写
Thread.sleep(1)
的时候,线程M 在 1ms 之后,便开始在while(true)
循环中检查td.isFlag()
的值,但是因为内存可见性的关系,线程M 并不能及时读取 线程T 中 flag 的值,所以此时导致了死循环;当写
Thread.sleep(1000)
的时候,M 在 1000ms 之后,开始在while(true)
循环中检查td.isFlag()
的值;但是 T 在 200ms 的时候,便将 flag 的值设为true
了,所以,M 在 1000ms 之后检测td.isFlag()
的值肯定是返回true
的,那么第一次判断便会返回true
,产生输出并跳出while(true)
循环。为了让 线程M 及时读取到 线程T 中 flag 的值,需要将 flag 使用
volatile
关键字进行修饰:那么每次对 flag 的修改,其他线程都立马可见。关于
volatile
Thread.sleep(1)
을 작성할 때 스레드 M은 1ms 후while(true)
루프에서td.isFlag() 검사를 시작합니다. 그러나 메모리 가시성으로 인해 스레드 M은 스레드 T의 플래그 값을 적시에 읽을 수 없으므로 이때 무한 루프가 발생합니다. 🎜 🎜
Thread.sleep(1000)
을 작성할 때 M은 1000ms 후에while(true)
루프에서td.isFlag()
를 확인하기 시작합니다. code>; 그러나 T는 200ms에서 flag 값을true
로 설정하므로 M은td.isFlag( 1000ms 이후 )
를 감지하여true
이면 첫 번째 판단은true
를 반환하고 출력을 생성하며while(true)
code> 루프에서 빠져나옵니다. 🎜 🎜스레드 M이 스레드 T의 flag 값을 적시에 읽으려면 flag를휘발성
키워드로 수정해야 합니다. 🎜 으아아아 🎜그러면 플래그에 대한 모든 수정 사항이 즉시 다른 스레드에 표시됩니다.휘발성
사용에 대해서는 내 블로그인 Java Multithreading (6): Use of the 휘발성 키워드 🎜를 참조하세요.다음 3가지 코드를 참고하시면 됩니다.
으아악 으아악 으아악첫번째는 멀티스레딩의 가시성 문제로 인해 무한루프가 발생할 수 있는 상황입니다.
두 번째는 이 문제를 해결하기 위해
synchronized
를 사용하는 것입니다.synchronized
解决此问题,大多数工作场景用这个好第三个是使用
volatile
세 번째는 이 문제를 해결하기 위해휘발성
을 사용하는 것입니다. 실제 시나리오에서는 제한이 상대적으로 크기 때문에 주의해서 사용하세요