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?


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章