java併發 - 自底向上的原理分析

来源:https://www.cnblogs.com/wuboyu/archive/2018/03/03/8502976.html
-Advertisement-
Play Games

事先聲明,我只是java併發的新手,這篇文章也只是我閱讀《java併發編程的藝術》一書(內容主要涉及前3章)的一些總結和感悟。希望大家能多多討論,對於錯誤的地方還請指出。 0. 簡介 程式的世界是有層次分明的,每層都對外封裝細節而提供一些方式或者說介面來提供功能,甚至是約束功能來換取正確性等等。那麼 ...


   

  事先聲明,我只是java併發的新手,這篇文章也只是我閱讀《java併發編程的藝術》一書(內容主要涉及前3章)的一些總結和感悟。希望大家能多多討論,對於錯誤的地方還請指出。

  0. 簡介

    程式的世界是有層次分明的,每層都對外封裝細節而提供一些方式或者說介面來提供功能,甚至是約束功能來換取正確性等等。那麼接下來,就用分層的思想作為靈魂,各種記憶體模型作為骨架,來簡單討論Java併發的原理。
 

  1. 處理器記憶體模型

    我們面對的第一個問題是,一個好的處理器要滿足什麼條件?就像考試的學生一樣,當然是做得又快,對得又多。對於處理器來說一般要滿足兩個條件:
    1. 效率
    2. 正確性
 

  1.1 效率

    對於效率來說,處理器提供了很多的機制來滿足這一點,並行,指令流水線,指令重排,緩存機制等等。但這些方式必須加以限制來保證正確性,或者說效率和正確性在一定程度上是相互制約的,我們必須加以權衡,合理折中。
 

  1.2 正確性

    那麼怎麼保證正確性呢?同樣除了處理器的一些內部的機制,比如禁止某些指令重排,緩存一致性,匯流排鎖,緩存鎖定等等,同時還向其上層提供了好的方法,比如說記憶體屏障,CAS等等,這些方法、機制會讓上層(通過合理的方式)更好的來保證程式的正確性,就像Java會提供volatile,synchronized等等方式來讓程式員(通過合理的方式)調用保證程式的線程安全。
    讓我們更加深入這個話題,一個程式怎麼樣才叫正確?要滿足什麼性質?簡單來說,有三條性質:
    1. 原子性,就是要麼全部做要麼全不做,需要硬體的配合,比如CAS。
    2. 可見性,由於緩存的存在,要讓一個處理器處理的結果對其他處理器可見,首先要把緩存寫入記憶體。
    3. 順序性,程式必須保持一定的順序依次的產生結果。

    註意,處理器的很多機制可以保持其中多種性質,比如記憶體屏障就可以把緩存刷新進入記憶體,而其他處理器的緩存無效來保證可見性,和通過禁止指令重排來保證順序性。比如匯流排鎖,緩存鎖定,緩存一致性就通過各種方式來保證順序性和原子性。
 

  2. java記憶體模型

    好了我們更上一層樓,我們剛剛說在下一層(處理器)提供了各種機制來保證效率和正確性,而這一層正是要使用這些機制來到達這一層,也就是JRE和編譯器的正確性和效率。
    JMM(即java記憶體模型)同處理器模型一樣,也有很多的機制,包括各種優化。對外也提供volatile,synchronized和臭名昭著的concurrent包。上層的程式員也要使用(合理的方式)這些Java語言和包來保證線程安全。以下簡單敘述一些本層次與上一層次的依賴(註意,synchronized因為JMM的優化可以分為3種)

    1. final域 -> 記憶體屏障

    2. volatile -> 記憶體屏障(位元組碼層次)-> 記憶體屏障(處理器層次)

    3. synchronized -> 偏向鎖 + 輕量級鎖 + 互斥鎖
    偏向鎖 -> CAS
    輕量級鎖 -> CAS
    互斥鎖 -> moniter -> 原子級處理器指令

    4. concurrent包 -> volatile + CAS

    註意CAS實現concurrent包中的原子操作可能會有三大問題:
    1. ABA問題。(解決辦法:在變數前增加版本號)
    2. 迴圈時間長開銷大。(解決辦法:pause指令)
    3. 只能保證一個共用變數的原子操作。(解決辦法:用鎖或著合併操作)

    JMM把各種控製程序順序性的機制抽象成文字形式,就是happens-before。其目的就是向Java開發者屏蔽特定平臺的底層細節,設計的程式只要遵守happens-before就可以保證正確性。
 

  3. 程式員

    這是最上面的層次,簡單來說就是來利用好下層提供的機制來更好的編程。我想這也是我們要學習java併發原理的原因。

 

 
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • persist(): 把數據以序列化的形式緩存在JVM的堆空間中; cache(): 與使用預設存儲級別調用persist()是一樣的; collect(): 只有當你的整個數據集能在單台機器的記憶體中放得下時,才能使用collect(),因此,collect() 不能用在大規模數據集上;把RDD 篩 ...
  • Description 學校組織了一次新生舞會,Cathy作為經驗豐富的老學姐,負責為同學們安排舞伴。有n個男生和n個女生參加舞會 買一個男生和一個女生一起跳舞,互為舞伴。Cathy收集了這些同學之間的關係,比如兩個人之前認識沒計算得出 a[i][j] ,表示第i個男生和第j個女生一起跳舞時他們的喜 ...
  • 整理了一下前端時間學習Java併發的筆記,大約有40篇。 1. Java併發基礎知識 "併發基礎(一) 線程介紹" "併發基礎(二) Thread類的API總結" "併發基礎(三) java線程優先順序" "併發基礎(四) java中線程的狀態" "併發基礎(五) 創建線程的四種方式" "併發基礎(六 ...
  • CDN 什麼是CDN 初學Web開發的時候,多多少少都會聽過這個名詞 CDN。 CDN在我沒接觸之前,它給我的印象是用來優化網路請求的,我第一次用到CDN的時候是在找JS文件時。當時找不到相對應的JS文件下載地址(之前一般我都是把JS下載下來,然後在項目中引用的。PS:當然了,我覺得大部分初學者都一 ...
  • 覆選框checkbox和單選框radio是web網站里經常會使用到的兩個控制項,那麼在web自動化測試的時候如何利用Selenium來操作這倆控制項呢?今天我們就來簡單入門練習一下! html測試頁面代碼如下: 從HTML代碼看,這裡面的覆選框checkbox和單選框radio都是input標簽,那麼我 ...
  • 解法一: 這種解法使用的是Brute Force演算法,即是暴力搜索匹配,時間複雜度較高 解法二: 這種解法的思想是計算兩個相同的字元之間的長度,好比作一個視窗在字元串上右邊框向右拉伸,若右邊框碰到視窗內已存在的字元,那麼左邊框向右拉伸到到視窗已存在字元的右邊,時間複雜度較低 github地址:htt ...
  • 研究了一些操作系統的概念,研究了I/O模式,著重研究了select、poll、epoll 的區別, ...
  • (一) 字元串 單引號、雙引號、三重引號都可以作為字元串的開始和結束,三重引號可以直接輸入多行字元串。三重引號可能一般是用來寫多行註釋。 (二) r和\ r使字元串成為原始字元串,忽略所有轉義字元。 \是轉義字元。 (三) 字元串下標和切片 (四) 字元串的in和not in (五) 改變大小寫 方 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...