concurrent之volatile

以戰養戰,邊學邊練,方有所成

  volatile輕量級的同步機制,保證可見性,不保證原子性,禁止指令重排  

  今天就分析一下volatile的關鍵字,內存可見性,在講這個之前,我們來看一下,線程是怎麼去處理數據的,我們都知道線程是cpu調度的單位,每個線程都是稀缺資源,創建線程會消耗cpu緩存和cpu運算資源,cpu在創建線程之後,線程具有自己的工作空間,java中的變量都是保存在主內存中,如果線程需要操作主內存,那麼就需要copy一份變量到自己的工作空間中,進行修改變量操作,操作完,再把操作後的數據寫入到主內存,jmm就是控制線程和主內存的變量輸入和輸出操作,如果這個變量被多個線程操作,當一個變量操作完,如果沒有內存可見性的操作,其他線程是不知道該變量被修改了

  總結:線程修改變量副本拷貝,發送給主線程,如果變量加了volatile,立馬通知給其他線程該變量修改完成  

  原子性:保證數據完整一致性,中間過程不可被分割,要麼成功,要麼失敗,沒有原子性,有可能寫覆蓋

  指令重排序:必須滿足數據依賴性,計算機在執行程序時,爲了提高性能,對編譯器優化重排,指令並行執行,內存系統重排

  禁止指令重排:通過插入內存屏障指令,禁止在內存屏障前後的指令執行重排序優化,避免線程執行亂序的情況

yield線程中的關鍵字,讓出線程執行,讓其他線程在準備中(Runnable),之後一起執行,Thread.activeCount(),一個程序運行必須有2個或以上線程,類線程和gc線程

  解決原子性問題:

  1. 加sync鎖
  2. 如果是變量可以使用AtomicInteger      
private static volatile SingletonDemo singletonDemo = null;
    
    /**
     * 雙端檢鎖
     * @return
     */
    private static SingletonDemo getSingleton(){
        if (singletonDemo == null){
            synchronized (SingletonDemo.class){
                if (singletonDemo == null){
                    singletonDemo = new SingletonDemo();
                }
            }
        }
        return singletonDemo;
    }

  

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