volatile是Java虚拟机提供的最轻量级的同步机制。当一个变量A被定义成volatile后,可以保证此变量对所有线程的可见性,这里的可见性是指,当一条线程修改了A的值,A的新值对于其他线程来说是可以“立即”得知的。
如下代码创建的5个线程,每个线程根据shutdownRequested的状态来切换执行的流程。
public class VolatileTest {
private static final int THREADS_COUNT = 5;
volatile static boolean shutdownRequested;
public static void doWork(String threadname) {
while(!shutdownRequested) {
//so some work.
}
System.out.println(threadname + " stopped...");
}
public static void main(String[] args) {
Thread[] threads = new Thread[THREADS_COUNT];
for(int i = 0; i < THREADS_COUNT; i++) {
threads[i] = new Thread(new Runnable() {
@Override
public void run() {
doWork("ThreadExcutedTime:" + System.currentTimeMillis());
}
});
threads[i].start();
}
try {
System.out.println("Sleep 2s begin");
Thread.sleep(2000);
System.out.println("Sleep 2s end");
shutdownRequested = true;
System.out.println("Stop thread...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出结果:
Sleep 2s begin
Sleep 2s end
Stop thread...
ThreadExcutedTime:1625193970262 stopped...
ThreadExcutedTime:1625193970236 stopped...
ThreadExcutedTime:1625193970276 stopped...
ThreadExcutedTime:1625193970290 stopped...
ThreadExcutedTime:1625193970212 stopped...
当shutdownRequested被声明为volatile类型后,最开始shutdownRequested为false,每个线程都在执行while循环,当2s后shutdownRequested设置为true时,5个线程“立即”结束while循环,执行后面的代码。
当我们去除shutdownRequested的volatile声明后:
/*volatile */static boolean shutdownRequested;
输出结果
Sleep 2s begin
Sleep 2s end
Stop thread...
可见五个线程仍在继续执行while循环,没有往下走,这是因为线程没有立即感知到shutdownRequested的状态变化。