也许实现 volatile 变量的规范使用仅仅是使用一个布尔状态标志,用于指示发生了一个重要的一次性事件,例如完成初始化或请求停机。
package test; public class Test { public boolean shutdownRequested= false; public void shutdown() { shutdownRequested = true; } public void doWork() { while (!shutdownRequested) { // do stuff } System.out.println("doWork end"); } public static void main(String[] args)throws Exception { Test test = new Test(); new Thread(new Runnable() { @Override public void run() { test.doWork(); } }).start(); System.out.println("main start>>>>>>>>>>>>>>>>>>"); Thread.sleep(2000); test.shutdown(); System.out.println("main end>>>>>>>>>>>>>>>>>>"); Thread.sleep(200000); } }
线程1执行doWork()的过程中,可能有另外的线程2调用了shutdown,所以boolean变量必须是volatile。
而如果使用 synchronized
块编写循环要比使用 volatile 状态标志编写麻烦很多。由于 volatile 简化了编码,并且状态标志并不依赖于程序内任何其他状态,因此此处非常适合使用 volatile。
这种类型的状态标记的一个公共特性是:通常只有一种状态转换;shutdownRequested
标志从false
转换为true
,然后程序停止。这种模式可以扩展到来回转换的状态标志,但是只有在转换周期不被察觉的情况下才能扩展(从false
到true
,再转换到false
)。此外,还需要某些原子状态转换机制,例如原子变量。