volatile
看到一张好图,忍不住。(首先你对volatile有一定认识,然后在看下面)
原理性理解volatile的使用限制条件:
1.对变量的写操作不依赖于当前值。
2.该变量没有包含在具有其他变量的不变式中。
2这点还没有理解,大咖有了解帮忙解释下。
1点通过下图就能很好的理解,首先它不是锁,所以并非线程安全,只是同步访问的免锁机制。
volatile修饰的变量,jvm虚拟机只是保证从主内存加载到线程工作内存的值是最新的。
即read到值肯定是最新的,但是read之后在线程中load及之后的时候,其他线程更新了volatile修饰的变量值,则这个线程中的值又是废值了。所以手册里写:volatile使用可能带来麻烦。。
所以你想用volatile写计数,在多线程下就不好使了。不过看windowmanager的code,具有有这么用的。。。又怀疑人生了,难道google菜逼么?还是理解的还是不够透彻。。。
哇,终于get到了,volatile作用:
下面的demo,如果这行没有volatile定义,当第一此退出acitivity的时候,没有问题,子线程会推出,但是再次进入这个activiy的时候,子线程则不会退出。
volatile boolean running = true;
public class StopThread extends Activity { //The way to stop a thread: //1. while(flag) //2.interrupt //3.stop, but do not use it. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Task task = new Task(); Thread thread = new Thread(task); thread.start(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } Log.d(TAG,"thread task i: "+task.i); //way 2 //thread.interrupt(); //way 1 task.running = false; Log.d(TAG,"exit first main thread i: "+task.i); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } Log.d(TAG,"Really exit main thread i: "+task.i+". Do your thread exit?"); } public class Task implements Runnable { volatile boolean running = true;//you can try boolean running = true; if you exit current activty, and enter again, the thread will no exit. int i = 0; @Override public void run() { //way 2 // while (!Thread.interrupted()) { // way 1 while (running) { i++; } Log.d(TAG, "exit task "+i); } } }
正常退出,及volatile修饰的时候:
03-30 10:44:15.777 30561 30561 D ThreadDemo: thread task i: 793829
03-30 10:44:15.777 30561 30561 D ThreadDemo: exit first main thread i: 793829
03-30 10:44:15.778 30561 30594 D ThreadDemo: exit task 793830
03-30 10:44:15.788 30561 30561 D ThreadDemo: Really exit main thread i: 793830. Do your thread exit?
异常,没有退出的情况:可以看到主线程sleep之后,拿到的i不一样,也就是子线程还在跑。而上面volatile修饰的则不会有这种情况。
03-30 10:49:35.104 1147 1147 D ThreadDemo: thread task i: 13783953
03-30 10:49:35.104 1147 1147 D ThreadDemo: exit first main thread i: 13854075
03-30 10:49:35.118 1147 1147 D ThreadDemo: Really exit main thread i: 15926097. Do your thread exit?