JAVA多線程之先行發生原則

一、引子  

  如果java內存模型中所有的有序性都僅僅依靠volatile和synchronized來完成,那么有一些操作會變得很繁瑣,但我們在編寫java并發代碼時并未感覺到這一點,這是因為java語言中有個先行發生原則(happens-before),通過這個原則,我們可以通過幾條規則一攬子解決并發環境下兩個操作之間是否可能存在沖突的所有問題。

二、定義

  先行發生是java內存模型中定義的兩項做錯之間的偏序關系,如果說操作A先行發生與操作B,其實就是說在發生操作B之前,操作A產生的影響能被操作B觀察到,“影響”包括修改了內存中共享變量的值、發送了消息、調用了方法等。

三、規則
  java內存模型中“天然的”的先行發生關系規則如下:
  1、程序次序規則:
    在一個線程內,按照程序代碼順序,,書寫在前面的操作先行發生于書寫在后面的操作,準確的說,應該是控制流程序而不是程序代碼順序,因為要考慮分支、循環等結構;
  2、管程鎖規則:
    一個unlock操作先行發生于后面對同一個鎖的lock操作,這里必須強調的是同一個鎖,“后面”指的是時間上的先后順序。
  3、volatile變量規則:
    對一個volatile變量的寫操作先行發生于后面對這個變量的讀操作,“后面”同樣是時間上的先后順序。
  4、線程啟動規則:
    Thread對象的start()方法先行發生于次線程的每一個動作;
  5、線程終止規則:
    線程中的所有操作都先行發生于對此線程的終止檢測,可以通過Thread.join()方法結束,Thread.isAlive()的返回值等手段檢測到線程已終止執行
  6、線程中斷規則:
    對線程interrupt()方法的調用先行發生于被中斷線程的代碼檢測到中斷事件的發生,可以通過Thread.interruptd()方法檢測到是否有中斷發生
  7、對象終結規則:
    一個對象的初始化完成(構造函數執行結束)先行發生于它的finalize()方法的開始
  8、傳遞性
    如果操作A先行發生于操作B,操作B先行發生于操作C,那么就可以認為操作A先行發生于操作C。

四、示例  

如下案例:

public class TestValue {private int value = 0;public int getValue() {return value;}public void setValue(int value) {this.value = value;}
}

  如果線程A調用了“setValue(1)”,線程B調用了同一個對象的“getValue()”方法,那么返回值是什么?
    答案是不確定,因為這里的操作不是線程安全的,它不滿足上述所有的 先行發生 規則。
  修復方法有好多種,這里列舉較為簡單的兩種:
  1)把getter/setter方法都定義為synchronized方法
  2)把value定義為volatile變量。

轉載于:https://www.cnblogs.com/hunterCecil/p/7406055.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282629.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282629.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282629.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

git工具 將源碼clone到本地指定目錄的三種方式

git工具 將源碼clone到本地指定目錄的三種方式 CreationTime--2018年7月27日15點34分 Author:Marydon 1.情景展示 運行git-bash.exe,輸入命令:git clone 下載源碼地址-->回車,結果發現項目被下載到了,git工具的安裝目錄下 如何…

[摘]全文檢索引擎Solr系列—–全文檢索基本原理

原文鏈接--http://www.importnew.com/12707.html 全文檢索引擎Solr系列—–全文檢索基本原理 2014/08/18 | 分類: 基礎技術, 教程 | 2 條評論 | 標簽: solr 分享到: 64 本文作者: ImportNew - 劉志軍 未經許可,禁止轉載…

優化-瀏覽器緩存和壓縮優化

一、減少HTTP請求 1.圖片地圖: 假設導航欄上有五幅圖片,點擊每張圖片都會進入一個鏈接,這樣五張導航的圖片在加載時會產生5個HTTP請求。然而,使用一個圖片地圖可以提高效率,這樣就只需要一個HTTP請求。 服務器端圖片…

匯新杯┃拼多多黃崢:普通的創業者,不普通的朋友圈_創成匯

本月26日晚,拼多多在美國納斯達克上市,開盤后便持續走高,收漲高達40.53%,這家從成立到上市不過短短2年10個月的企業,是近四年來最大中概股IPO。拼多多創始人黃崢身家一夜暴漲到138.5億美元。在拼多多之前,黃…

NCC CAP 6.2 版本正式發布

原文:https://www.cnblogs.com/savorboard/p/cap-6-2.html作者:楊曉東前言今天,我們很高興宣布 CAP 發布 6.2 版本正式版,在這個版本中我們主要做了一些功能優化,以及針對目前已經發現的幾個 BUG 進行了修復了。那么&a…

pdksh 包

安裝oracle gi,rac 時經常會碰到 pdksh 的檢測失敗,可以從這個網站下載需要的包 http://rpm.pbone.net/ rpm -q ksh-* rpm -e ksh-* rpm -ivh ./pdksh* 或者參考 Requirements for Installing Oracle 11gR2 RDBMS on RHEL6 or OL6 64-bit (x86-64) (文…

sysctl.conf工作原理

2019獨角獸企業重金招聘Python工程師標準>>> sysctl.conf工作原理 sysctl命令被用于在內核運行時動態地修改內核的運行參數,可用的內核參數在目錄/proc/sys中。它包含一些TCP/IP堆棧和虛擬內存系統的高級選項, 這可以讓有經驗的管理員提高引人…

CDN加速

一、CDN的概念 全稱是Content Delivery Network,即內容分發網絡。 其基本思路是: 盡可能避開互聯網上有可能影響數據傳輸速度和穩定性的瓶頸和環節,使內容傳輸的更快、更穩定。 通過在網絡各處放置節點服務器所構成的在現有的互聯網基礎之上的一層智…

修復刪除/var/lib/dpkg目錄后,無法使用apt-get命令問題

2019獨角獸企業重金招聘Python工程師標準>>> Unfortunately Ive deleted dpkg directory while removing the lock. By mistake I typed rootsam:~$ rm -r /var/lib/dpkgNow when I am trying to install/uninstall packages it shows me following error. E: Could…

動態加載vs靜態加載

動態加載: 1:靈活,可以在需要的時候用LoadLibrary進行加載,在不需要的時候用FreeLibrary進行卸載,這樣可以不必占用內存。2:可以在沒有dll時候發現,而不致程序報錯。3:加載程序中有條…

Webpack前端打包工具

一、安裝 安裝Webpack之前需要安裝nodejs,然后用npm安裝: $ npm install webpack -g &nsbp;運行以上命令就將Webpack安裝到了全局環境中。 但是通常我們會將Webpack只安裝到項目的依賴中: $ cd /www/webpack_demo1 // 進入項目目錄,確保該目錄…

動態語言靜態化

一、什么是動態語言靜態化 將現有PHP等動態語言的邏輯代碼生成為靜態html文件,用戶訪問動態腳本重定向到靜態html的過程 注 : 對實時性要求不高的頁面才適合去做動態語言靜態化 二、為什么要靜態化 1. 動態腳本通常會做邏輯計算和數據查詢,訪問量越大,服務器壓力越大 2. 訪…

WPF-06 樣式(Style)

在我們前面介紹資源的時候&#xff0c;我們提到了樣式表&#xff0c;如果你之前是做Web開發的&#xff0c;你會發現Style有點類似于Web中的CSS。控件級別樣式我們可以在控件級別定義自己的樣式&#xff0c;控件級別的樣式是優先級最高的<Window x:Class"Example_06.Sel…

構建Squid代理服務器-傳統代理、透明代理、反向代理

Squid是Linux系統中最常用的一款開源代理服務軟件&#xff0c;主要提供緩存加速和應用層過濾控制的功能&#xff0c;可以很好的實現HTTP、FTP、DNS查詢以及SSL等應用的緩存代理。 正向代理&#xff1a;根據實現的方式不同&#xff0c;代理服務可分為傳統代理和透明代理。 傳統代…

Struts2之初識

Struts2教程 第一章 初識Struts2 主頁&#xff1a;http://struts.apache.org/ 優勢&#xff1a;用戶請求&#xff0c;模塊處理&#xff0c;頁面展現。適用于企業級開發&#xff0c;便于維護。 配置&#xff1a;web.xml中添加的核心控制器 <filter> <filter-name>St…

數據庫緩存層

一 常見的緩存形式 : 1.文件緩存 (為了避免I/O開銷,盡量使用內存緩存) 2.內存緩存 二 為什么要使用緩存 緩存數據是為了讓客戶端很少甚至不訪問數據庫服務器進行的數據查詢,高并發下,能最大程度降低對數據庫服務器的訪問壓力 一般的數據請求: 用戶請求->數據查詢->…

python面試題~反射,元類,單例

1 什么是反射&#xff1f;以及應用場景&#xff1f; test.py def f1():print(f1) def f2():print(f2) def f3():print(f3) def f4():print(f4) a 1 復制代碼import test as ss ss.f1() ss.f2() print(ss.a) 復制代碼我們要導入另外一個模塊,可以使用import.現在有這樣的需求,我…

僅有50Mb大小的cli即可搞定大廠才能玩的CloudIDE丨SmartIDE

作者&#xff1a;徐磊&#xff0c;開源云原生SmartIDE創始人、LEANOSFT創始人/首席架構師/CEO&#xff0c;微軟最有價值專家MVP/微軟區域技術總監Regional Director&#xff0c;華為云最有價值專家。從事軟件工程咨詢服務超過15年時間&#xff0c;為超過200家不同類型的企業提供…

idea-spark-sbt 打包jar

1、打開idea下的terminal窗口 2、只打包部分項目 sbt insight-import/clean insight-import/assembly 這表示只打包主目錄下的insight-import項目 &#xff0c;先清理&#xff08;clean&#xff09;再打包&#xff08;assembly&#xff09;不能用package&#xff0c;這個不會打…