看到一張好圖,忍不住。(首先你對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?