JAVA併發-併發框架(一)

来源:https://www.cnblogs.com/xiongchang95/archive/2018/10/23/9837134.html
-Advertisement-
Play Games

java併發的一系列框架和技術主要是由java.util.concurrent 包所提供。包下的所有類可以分為如下幾大類: locks部分:顯式鎖(互斥鎖和速寫鎖)相關; atomic部分:原子變數類相關,是構建非阻塞演算法的基礎; executor部分:線程池相關; collections部分:併發 ...


java併發的一系列框架和技術主要是由java.util.concurrent 包所提供。包下的所有類可以分為如下幾大類:

  • locks部分:顯式鎖(互斥鎖和速寫鎖)相關;
  • atomic部分:原子變數類相關,是構建非阻塞演算法的基礎;
  • executor部分:線程池相關;
  • collections部分:併發容器相關;
  • tools部分:同步工具相關,如信號量、閉鎖、柵欄等功能

整體實現技術可按照依賴級別分為以下三層:

    高層類

Lock  同步工具  併發容器  Executor/ExecutorCompletionService

  基礎類

AQS  非阻塞數據結構  原子變數類

   底層原理

volatile變數的讀/寫  CAS

一、volatile

  保證線程之間操作的可見性,避免操作的重排序,但不保證原子性(i++)。

  由於 Java 記憶體模型(JMM)規定,所有的變數都存放在主記憶體中,而每個線程都有著自己的工作記憶體(高速緩存)。

  在當前的Java記憶體模型下,線程可以把變數保存在本地記憶體(比如機器的寄存器)中,而不是直接在主存中進行讀寫。這就可能造成一個線程在主存中修改了一個變數的值,而另外一個線程還繼續使用它在寄存器中的變數值的拷貝,造成數據的不一致。

  Volatile修飾的成員變數在每次被線程訪問時,都強迫從共用記憶體中重讀該成員變數的值;當成員變數發生變化時,強迫線程將變化值回寫到共用記憶體。由於使用 volatile 屏蔽掉了 VM 中必要的代碼優化,所以在效率上會低效一些。

二、CAS無鎖演算法

  CAS(comapre and swap):CAS是一項樂觀鎖技術,其核心思想為衝突檢測和數據更新。Java對於CAS支持是利用sun.misc.Unsafe這個類通過JNI調用CPU底層指令實現Unsafe.compareAndSwapInt操作。其主要實現思路為:將記憶體值V與舊的預期值E,如果相同則更新為U,不相同則由上層系統迴圈獲取實際值後,再次調用此CAS演算法。最主要的應用就在原子變數類的具體實現中。

 

 

將記憶體值V與舊的預期值E,如果相同則更新為U,不相同,返回記憶體值給用戶。

Unsafe類提供了硬體級別的原子操作來實現這個CAS

但CAS存在問題:ABA問題/迴圈時間長開銷大/只能保證一個共用變數的原子操作

ABA:如棧結構(A-B),線程T1要移除A,B變棧頂,,線程T2將結構變為A-C-D,,此時T1進行CAS衝突檢測發現A沒變,但實際上整個棧結構變了,此時進行操作會覆蓋掉C-D,解決辦法是使用原子類AtomicStampedReference來保證整個棧的一致性。

 

對於線程衝突較輕,使用CAS能夠避免加鎖和釋放鎖的操作,消耗CPU資源。

對於線程衝突較重,CAS容易產生自旋,即不停比較然後失敗重試,浪費CPU。

三、AQS及其他同步工具

  AbstractQueuedSynchronizer抽象隊列同步器,定義了多線程訪問資源的同步框架。用於構建鎖和其他同步組件CountDownLatch等的基本框架。使用一個volatile(代表共用資源)來維護狀態,通過內置的FIFO隊列來完成資源獲取線程的排隊工作。如果被請求的共用資源空閑,則將當前請求資源的線程設置為有效的工作線程,並且將共用資源設置為鎖定狀態。如果被請求的共用資源被占用,那麼就需要一套線程阻塞等待以及被喚醒時鎖分配的機制,這個機制AQS是用CLH隊列(帶頭節點的雙向非迴圈鏈表)鎖實現的,即將暫時獲取不到鎖的線程加入到隊列中。 

  AQS兩類應用場景:Exclusive(資源獨占,只有一個線程能執行,如ReentrantLock)和Share(資源共用,多個線程可同時執行,如Semaphore/CountDownLatch)

 

  1.CountDownLatch: 倒計時器,同步工具類,允許一個或多個線程,等待其他一組線程完成操作,再繼續執行。在CountDownLatch 上定義兩種操作:CountDown.countDown表示該線程工作結束(計數器減一)、CountDown.await當前線程阻塞,等待其他工作線程結束(計數器為0)

 

  2.CyclicBarrier:線程屏障,同步工具類,允許一組線程相互之間等待,達到一個共同點,再繼續執行。能夠重置並多次使用,並且能夠獲取阻塞線程數量;不會阻塞主線程。

 

  3.Semaphore:信號量,用於控制線程的併發數量。在信號量上我們定義兩種操作: acquire(獲取) 和 release(釋放)。當一個線程調用acquire操作時,它要麼通過成功獲取許可(許可減1),要麼一直等下去,直到有線程釋放許可,或超時。release(釋放)實際上會將許可的值加1,然後喚醒等待的線程。

  使用Seamphore(2),創建了多少線程(5),實際就會有多少線程執行(5),只是可同時執行的線程數量會受到限制(2)。但使用線程池(25),不管你創建多少線程實際可執行的線程數是一定的(2)。

 

  4.Exchanger:交換者,實現線程間的相互數據交換或通信。提供一個同步點,當兩個線程都達到該同步點時,則進行交換數據,可以多個進行隨機交換,但必須為偶數個。無鎖,通過迴圈 cas 來實現線程安全。eg:String data2 = (String) exchanger.exchange(data1)。

四、非阻塞數據結構

同步集合:Vector、HashTable,同步集合包裝類/Collections.synchronizedMap()和Collections.synchronizedList()---同步集合會對整個May或List加鎖。

ConcurrentHashMap:HashMap的併發級別,通過繼承自ReentrantLock的Segment來對Hahs表進行分段鎖,提高了併發效率

ConcurrentQueue也是通過同樣的方式來提高併發性能的,子類ConcurrentLinkedQueue。例子:多線程賣票。

CopyOnWriteArrayList:寫時複製容器,複製該容器進行寫操作,將當前容器進行Copy,複製出一個新的容器,然後向新的容器里添加元素,添加完元素之後,再將原容器的引用指向新的容器。這樣做的好處是我們可以對CopyOnWrite容器進行併發的讀,而不需要加鎖,因為在當前讀的容器中不會添加任何元素。所以CopyOnWrite容器是一種讀寫分離的思想,讀和寫對應不同的容器。

BlockingQueue:阻塞隊列,併發容器,沒有元素時-讀取會堵塞,元素滿時-加元素會阻塞。適合消費者生產者模式,其中ExecutorCompletionService就是將LinkedBlockingQueue和Executor結合管理線程返回結果。

ArrayBlockingQueue

有界隊列,使用一個ReentrantLock 鎖。

LinkedBlockingQueue

無界隊列,內部使用ReentrantLock實現插入鎖(putLock)和取出鎖(takeLock),fixedThreadPool用的這個。

DelayQueue

其中的對象只能在其到期時才能從隊列中取走。這種隊列是有序的,即隊頭對象的延遲到期時間最長。但是要註意的是,不能將null元素放置到這種隊列中.eg:處理超時的客戶端鏈接、超時的緩存對象


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

-Advertisement-
Play Games
更多相關文章
  • 緩存穿透 概念 訪問一個不存在的key,緩存不起作用,請求會穿透到DB,流量大時DB會掛掉。 解決方案 1. 採用布隆過濾器,使用一個足夠大的bitmap,用於存儲可能訪問的key,不存在的key直接被過濾; 2. 訪問key未在DB查詢到值,也將空值寫進緩存,但可以設置較短過期時間。 緩存雪崩 概 ...
  • 下麵總結並演示了 Redis 的 常用管理命令、key 操作、字元串、集合、列表、散列類型的操作命令。 你需要掌握的 Redis 知識 "史上最全 Redis 高可用解決方案總結" "為什麼分散式一定要有Redis?" "Spring Boot Redis Cluster 實戰乾貨" "Spring ...
  • 系統介紹: 1.系統採用主流的 SSM 框架 jsp JSTL bootstrap html5 (PC瀏覽器使用) 2.springmvc +spring4.3.7+ mybaits3.3 SSM 普通java web(非maven, 附贈pom.xml文件) 資料庫:mysql 3.開發工具:my ...
  • GraphQuery " " " " " " " " " " " " GraphQuery is a query language and execution engine tied to any backend service. It is . Project Address: "GraphQue ...
  • Learun FrameWork 強大工作流引擎,讓OA更智能 互聯網的發展促使企業在信息化的道路上不斷探索,而隨著企業信息化進程的不斷深入,OA協同辦公的概念也逐步進入大眾的視野。 OA的選型關乎企業的生存發展,除了需要重視“OA技術、OA品牌、OA產品、OA服務”四大要素之外,更重要的其實是讓O ...
  • 前言: 在生產環境中,未避免單點故障,每個微服務都會做高可用部署。 通白的說,就是每一個一模一樣的服務會根據需求提供多分在多台機器上。 那麼在大併發的情況下,如何分配服務可以快速得到響應,就成為了我們要解決的問題。 Ribbon就是一款優秀的客戶端負載均衡機制。 什麼是客戶端負載均衡呢? 就是由服務 ...
  • 本文探討如下幾個問題: 什麼是架構屬性 約束和架構屬性的關係 有哪些架構屬性 各個架構屬性涉及知識點 什麼是架構屬性 首先,問個很簡單的問題!請看下麵的Java代碼: 請問上面的代碼中: name和age被稱為Person這個類的什麼? skill又稱為Person這個類的什麼呢? name和age ...
  • 文章提綱 概述要點 理論基礎 詳細步驟 總結 概述要點 理論基礎 詳細步驟 總結 概述要點 設計模式的產生,就是在對開發過程進行不斷的抽象。 我們先看一下之前訪問數據的典型過程。 在Controller中定義一個Context, 例如: private AccountContext db = new ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...