volatile 也是多线程的解决方案之一。**volatile 可以保证可见性,可是不能保证原子性。**它只能做用于变量,不能做用于方法。当一个变量被声明为 volatile 的时候,任何对该变量的读写都会绕太高速缓存,直接读取主内存的变量的值。缓存
如何理解直接读写主内存的值:回到 多线程生成的缘由(Java内存模型与i++操做解析) ,在 i++ 操做的时候,当 进行 执行引擎 对 变量 进行 + 1 以后,原来 是应该写入到 本地内存中,再由本地内存写入到主内存中,可是 因为 变量使用了 volatile 的修饰,因此 该值不会通过本地内存,而是直接写入到 主内存中去。 读取也是一样的道理。多线程
使用volatile 有两点须要注意的地方:线程
public class Test { public static volatile int i = 0; public static void main(String args[]){ new Thread(new Runnable(){ public void run(){ for(int j = 0; j < 10000; j++) i++; System.out.println("Thread1 end..."); } }).start(); new Thread(new Runnable(){ public void run(){ for(int j = 0; j < 10000; j++) i++; System.out.println("Thread2 end..."); } }).start(); i++; try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("i = " + i); } }
private Date start; private Date end; public void setInterval(Date newStart, Date newEnd) { // 检查start<end是否成立, 在给start赋值以前不变式是有效的 start = newStart; // 可是若是另外的线程在给start赋值以后给end赋值以前时检查start<end, 该不变式是无效的 end = newEnd; // 给end赋值以后start<end不变式从新变为有效 }
最后,关于何时使用 volatile,通常是用来当作标记来使用。好比说,当shutdown() 方法被调用的时候,全部的 doWork() 方法都会停下来。code