Java并發中正確使用volatile

jopen 10年前發布 | 30K 次閱讀 Java Java開發

并發 - 定義

悲觀鎖 - Pressimistic locking

  1. 一個線性在執行一個操作時持有對一個資源的獨占鎖。(互斥)

    </li>

  2. 一般用在沖突比較可能發生的場景下

    </li> </ol>

    樂觀鎖 - Optimistic locking

    1. 嘗試采用原子操作,而不需要持有鎖;沖突可被檢測,如果發生沖突,具有相應的重試邏輯

      </li>

    2. 通常用在沖突較少發生的場景下

      </li> </ol>

      非阻塞算法 - Non-blocking algorithm

      1. 算法確保對線程間競爭共享資源時候,不會因為互斥而使任一線程的執行無限延遲;

        </li> </ol>

        無鎖算法 - Lock-free algorithm

        1. 如果系統整個流程的執行是無阻塞的(系統某一部分可能被短暫阻塞),這種非阻塞算法就是無鎖的。

          </li>

        2. 無鎖算法比傳統的基于鎖的算法對系統的開銷更小,且更容易在多核多CPU處理器上擴展;

          </li>

        3. 在實時系統中可以避免鎖帶來的延遲;

          </li>

        4. CAS (compare and swap)或LL/SC(load linked/store conditional),以及內存屏障相關的指令經常被用在算法實現中。

          </li> </ol>

          無等待算法 - Wait-free algorithm

          1. 如果每個線程的執行都是無阻塞的,這種非阻塞算法就是無等待的(比無鎖算法更好)

            </li> </ol>

            Java的并發

            1. Java的內存模型并不保證一個線程可以一直以程序執行的順序看到另一個線程對變量的修改,除非兩個線程都跨越了同一個內存屏障。(Safe publication)

              </li> </ol>

              Java內存模型

              代碼順序規則

              1. 一個線程內的每個動作 happens-before 同一個線程內在代碼順序上在其后的所有動作

                </li> </ol>

                volatile變量規則

                1. 對一個volatile變量的讀,總是能看到(任意線程)對這個volatile變量最后的寫入

                  </li> </ol>

                  傳遞性

                  1. 如果A happens-before B, B happens-before C,那 A happens-before C

                    </li> </ol>

                    Safe publication案例

                    class VolatileExample {
                        int x = 0;
                        volatile int b = 0;
                        private void write() {
                            x = 5;
                            b = 1;
                        }
                        private void read() {
                            int dummy = b;
                            while (x!=5) {
                            }
                        }
                        public static void main(String[] args) throws Exception {
                            final VolatileExample example = new VolatileExample();
                            Thread thread1 = new Thread(new Runnable() {
                                public void run() {
                                    example.write();
                                }
                            });
                            Thread thread2 = new Thread(new Runnable() {
                                public void run() {
                                    example.read();
                                }
                            });
                            thread1.start();
                            thread2.start();
                            thread1.join();
                            thread2.join();
                        }
                    }

                    </div> </div>

                    Java并發中正確使用volatile

                    x并不需要定義為volatile, 程序里可以有需要類似x的變量,我們只需要一個volatile變量b來確保線程a能看到線程1對x的修改:

                    1. 根據happens-before的傳遞規則,線程1的x=5; happens-before b=1;; 線程2的int dummy = b; happens-beforewhile(x!=5);

                      </li>

                    2. 根據volatile變量規則,線程2的b=1; happens-before int dummy=b;

                      </li>

                    3. 根據傳遞性,x=5; happens-before while(x!=5);

                      </li> </ol>

                      JSR-133

                      在JSR-133之前的舊Java內存模型中,雖然不允許volatile變量之間重排序,但舊的Java內存模型仍然會允許volatile變量 與普通變量之間重排序。JSR-133則增強了volatile的內存語義:嚴格限制編譯器(在編譯器)和處理器(在運行期)對volatile變量與普 通變量的重排序,確保volatile的寫-讀和監視器的釋放-獲取一樣,具有相同的內存語義。

                      延伸閱讀: JSR-133: JavaTM Memory Model and Thread Specification, The JSR-133 Cookbook for Compiler Writers

                      參考鏈接

                      1. http://2011.lucene-eurocon.org/attachments/0002/8787/Busch_推ter_realtime_search_eurocon_11.pdf

                        </li>

                      2. http://www.rossbencina.com/code/lockfree

                        </li>

                      3. http://rethinkdb.com/blog/lock-free-vs-wait-free-concurrency/

                        </li>

                      4. http://www.infoq.com/cn/articles/java-memory-model-4

                        </li>

                      5. JSR-133: JavaTM Memory Model and Thread Specification

                        </li>

                      6. The JSR-133 Cookbook for Compiler Writers

                        </li> </ol> 原文地址: http://hugozhu.myalert.info/2013/06/30/38-java-volatile-variable.html

                     本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
                     轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
                     本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!