Java 併發編程關鍵字(volatile、synchronized)語義及其實現細節

一、Java 程序執行過程概述

Java 源文件編譯成java字節碼,執行時JVM將字節碼載入到內存中 ,再由語言解釋器和JIT轉換成所在機器的彙編指令交給CPU執行。

二、Java 併發編程面對的挑戰

Java 語言設計之初即選擇支持多線程,java先天支持多線程的特性使得其良好的適應了現代CPU運算能力的提升及多核心的發展方向。併發編程的目的是,在保證程序運行結果正確的前提下儘可能的壓榨CPU、IO和總線從而提升程序的執行效率。併發編程的挑戰就是如何保證程序在多線程執行時能夠得到正確的結果。程序的運行可以簡單的理解爲{輸入數據}---->程序操作數據---->{輸出結果};所以多個線程同時執行一段代碼時要保證正確性就是要保證對共享變量進行有序性的、原子性的、一致性的操作,即要避免三種意外情況 ;一、避免編譯器和CPU對指令優化重新排序導致的執行順序錯誤,二、避免線程上下文切換導致的導致的原子性問題,三、避免本地內存數據的操作結果對其他線程不可見的問題。

三、JAVA 併發編程關鍵字

1、volatile 

volatile 保證共享變量的可見性,意思是當一個線程修改了共享變量時,其他線程能夠讀到這個修改後的值。Java語言規範第3版中對 volatile 定義如下:Java 編程語言允許線程訪問共享變量,爲了確保共享變量能夠被準確和一致的更新,線程應該確保通過排他鎖單獨獲得這個變量。

實現原理:volatile  變量更新時,處理器聲言Lock信號,鎖定緩存變量的主內存將更新刷新到主存。其他處理器通過總線嗅探技術探測到主存刷新,則將其對應緩存行數據設置爲失效。

2、synchronized

synchronized 同步鎖 確保同一時刻只有個線程執行被鎖定的代碼。synchronized 鎖有三種形式 1、synchronized  方法是鎖定當前實例對象,2、synchronized 靜態方法是鎖定當前類的Class對象,3、對於synchronized (Object)代碼塊是鎖定Object對象。

實現原理:線程執行到synchronized 代碼塊的起始位置時嘗試獲取synchronized 鎖定的對象的 monitor,當monitor被持有後 synchronized代碼將處於鎖定狀態,其他線程需要等待到monitor被持有線程釋放後重新嘗試獲取monitor。

3、volatile 和 synchronized 比較

volatile 執行成本低不會引起線程上下文切換和調度,鎖定的是單個變量。

synchronized  會引起線程上下文切換和調度,鎖定的是一段代碼。

 

 

 

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