volatile变量是 Java 提供的另一种同步机制,保证线程之间的可见性,即一个线程对共享变量的修改能够立即被另一个线程看到。
使用也很简单,直接在变量前加 volatile 关键词:
public class VolatileTest { private volatile boolean stop = true; public void test() { while(stop) { System.out.println("running"); } System.out.println("quit while loop"); } public static void main(String[] args) { VolatileTest test = new VolatileTest(); new Thread(()->test.test()).start(); try { TimeUnit.SECONDS.sleep(5); test.stop = false; } catch (InterruptedException e) { e.printStackTrace(); } } }
但是它只是保证线程之间的可见性,不能替代 synchronized 的实现原子性,如下代码运行,最大值并不是499:
public class VolatileTest2 { private volatile int count = 0; public void add() { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(count++); } public static void main(String[] args) { VolatileTest2 test = new VolatileTest2(); for (int i=0; i<500; i++) { new Thread(() -> test.add(),i+"add").start(); } } }
另外一个作用就是禁止 cpu 指令重排序。
cpu 在执行指令的时候,为了提高效率,会并发的执行指令,可能会进行指令的重排序。