java的volatile关键字小记
用在多线程,同步变量。 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B。只在某些动作时才进行A和B的同步。因此存在A和B不一致的情况。volatile就是用来避免这种情况的。volatile告诉jvm, 它所修饰的变量不保留拷贝,直接访问主内存中的(也就是上面说的A)
=========================分割线1=================================
在Java内存模型中,有main memory,每个线程也有自己的memory (例如寄存器)。为了性能,一个线程会在自己的memory中保持要访问的变量的副本。这样就会出现同一个变量在某个瞬间,在一个线程的memory中的值可能与另外一个线程memory中的值,或者main memory中的值不一致的情况。
一个变量声明为volatile,就意味着这个变量是随时会被其他线程修改的,因此不能将它cache在线程memory中。以下例子展现了volatile的作用:
public class StoppableTask extends Thread { private volatile boolean pleaseStop; public void run() { while (!pleaseStop) { // do some stuff... } } public void tellMeToStop() { pleaseStop = true; }} int i1; int geti1() {return i1;} volatile int i2; int geti2() {return i2;} int i3; synchronized int geti3() {return i3;} package mythread; public class JoinThread extends Thread { public static volatile int n = 0 ; public void run() { for ( int i = 0 ; i < 10 ; i ++ ) try { n = n + 1 ; sleep( 3 ); // 为了使运行结果更随机,延迟3毫秒 } catch (Exception e) { } } public static void main(String[] args) throws Exception { Thread threads[] = new Thread[ 100 ]; for ( int i = 0 ; i < threads.length; i ++ ) // 建立100个线程 threads[i] = new JoinThread(); for ( int i = 0 ; i < threads.length; i ++ ) // 运行刚才建立的100个线程 threads[i].start(); for ( int i = 0 ; i < threads.length; i ++ ) // 100个线程都执行完后继续 threads[i].join(); System.out.println( " n= " + JoinThread.n); } } package mythread; public class JoinThread extends Thread { public static int n = 0 ; public static synchronized void inc() { n ++ ; } public void run() { for ( int i = 0 ; i < 10 ; i ++ ) try { inc(); // n = n + 1 改成了 inc(); sleep( 3 ); // 为了使运行结果更随机,延迟3毫秒 } catch (Exception e) { } } public static void main(String[] args) throws Exception { Thread threads[] = new Thread[ 100 ]; for ( int i = 0 ; i < threads.length; i ++ ) // 建立100个线程 threads[i] = new JoinThread(); for ( int i = 0 ; i < threads.length; i ++ ) // 运行刚才建立的100个线程 threads[i].start(); for ( int i = 0 ; i < threads.length; i ++ ) // 100个线程都执行完后继续 threads[i].join(); System.out.println( " n= " + JoinThread.n); } }