1. 程式人生 > >程式設計體系結構(05):Java多執行緒併發

程式設計體系結構(05):Java多執行緒併發

本文原始碼:[GitHub·點這裡](https://github.com/cicadasmile) || [GitEE·點這裡](https://gitee.com/cicadasmile) # 一、多執行緒導圖 ![](https://img2020.cnblogs.com/blog/1691717/202010/1691717-20201003093330167-1595744136.png) # 二、多執行緒基礎 **1、基礎概念** 執行緒是作業系統能夠進行運算排程的最小單位,包含在程序之中,是程序中的實際運作單位。一條執行緒指的是程序中一個單一順序的控制流,一個程序中可以併發多個執行緒,每條執行緒並行執行不同的任務。 **2、建立方式** 繼承Thread類、實現Runnable介面、基於Callable和Future介面、Timer是後臺執行緒、執行緒池。 **3、執行緒狀態** ![](https://img2020.cnblogs.com/blog/1691717/202010/1691717-20201003093320851-808254390.jpg) 狀態描述:初始狀態、執行狀態、阻塞狀態、等待狀態、超時等待狀態、終止狀態。 **4、執行機制** ![](https://img2020.cnblogs.com/blog/1691717/202010/1691717-20201003093312076-1500807937.jpg) JVM中一個應用是可以有多個執行緒並行執行,執行緒被一對一對映為服務所在作業系統執行緒,排程在可用的CPU上執行,啟動時會建立一個作業系統執行緒;當該執行緒終止時,這個作業系統執行緒也會被回收。 **5、記憶體模型** ![](https://img2020.cnblogs.com/blog/1691717/202010/1691717-20201003093300390-1507978859.png) 在虛擬機器啟動執行時,會建立多個執行緒,資料區中有的模組是執行緒共享的,有的是執行緒私有的: 執行緒共享:元資料區、堆Heap; 執行緒私有:虛擬機器棧、本地方法棧、程式計數器; 單個CPU在特定時刻只能執行一個執行緒,所以多執行緒通過幾塊空間的使用,然後不斷的爭搶CPU的執行時間段。 # 三、常見概念 **1、執行緒優先順序** 執行緒排程器傾向執行執行緒優先順序高的執行緒,執行緒優先順序高說明獲取CPU資源的概率高,或者獲取的執行時間分片多,被執行的概率高但不代表優先順序低的一定最後執行。 **2、守護執行緒** 守護執行緒是支援輔助型執行緒,主要在程式中起到排程和支援性作用,當Jvm中非守護執行緒全部結束,守護執行緒也就會結束。 **3、執行緒加入** 執行緒A中,執行執行緒B的加入方法,那麼A執行緒就會等待執行緒B執行完畢再返回繼續執行。 **4、本地執行緒** ThreadLocal也叫做執行緒本地變數,為變數在每個執行緒中的建立副本,每個執行緒可以訪問自己內部的副本變數,執行緒之間互不相互影響。 # 四、執行緒安全 在上圖執行緒與記憶體空間的佔用方式看,線上程訪問共享記憶體塊時,保證執行緒安全就很有必要。 **1、同步控制** Synchronized關鍵字同步控制,可以修飾方法,修飾程式碼塊,修飾靜態方法等,同步控制的資源少,可以提高多執行緒效率。 **2、加鎖機制** Lock介面:Java併發程式設計中資源加鎖的根介面之一,規定了資源鎖使用的幾個基礎方法。 ReentrantLock類:實現Lock介面的可重入鎖,即執行緒如果獲得當前例項的鎖,並進入任務方法,線上程沒有釋放鎖的狀態下,可以再次進入任務方法,特點:互斥排它性,即同一個時刻只有一個執行緒進入任務。 Condition介面:描述可能會與鎖有關聯的條件變數,提供了更強大的功能,例如線上程的等待/通知機制上,Conditon可以實現多路通知和選擇性通知。 **3、Volatile關鍵字** volatile修飾成員變數,不能修飾方法,即標識該執行緒在訪問這個變數時需要從共享記憶體中獲取,對該變數的修改,也需要同步重新整理到共享記憶體中,保證了變數對所有執行緒的可見性。 # 五、執行緒通訊 執行緒是個獨立的個體,但是線上程執行過程中,如果處理同一個業務邏輯,可能會產生資源爭搶,導致併發問題,甚至死鎖現象,執行緒之間協調工作,就需要通訊機制來保障。 **1、基礎方法** 相關方法是Java中Object層級的基礎方法,任何物件都有該方法:notify()隨機通知一個在該物件上等待的執行緒,使其結束wait狀態返回;wait()執行緒進入waiting等待狀態,不會爭搶鎖物件,也可以設定等待時間; **2、等待/通知機制** 等待/通知機制,該模式下指執行緒A在不滿足任務執行的情況下呼叫物件wait()方法進入等待狀態,執行緒B修改了執行緒A的執行條件,並呼叫物件notify()或者notifyAll()方法,執行緒A收到通知後從wait狀態返回,進而執行後續操作。兩個執行緒通過基於物件提供的wait()/notify()/notifyAll()等方法完成等待和通知間互動,提高程式的可伸縮性。 **3、管道流通訊** 管道流主要用於在不同執行緒間直接傳送資料,一個執行緒傳送資料到輸出管道,另一個執行緒從輸入管道中讀取資料,進而實現不同執行緒間的通訊。 # 六、執行緒池 **1、Executor介面** Executor系統中,將執行緒任務提交和任務執行進行了解耦的設計,Executor有各種功能強大的實現類,提供便捷方式來提交任務並且獲取任務執行結果,封裝了任務執行的過程,不再需要Thread().start()方式,顯式建立執行緒並關聯執行任務。 **2、核心引數** ![](https://img2020.cnblogs.com/blog/1691717/202010/1691717-20201003093241473-428840427.png) **3、相關API類** ![](https://img2020.cnblogs.com/blog/1691717/202010/1691717-20201003093224653-1464057782.jpg) 執行緒池任務:核心介面:Runnable、Callable介面和介面實現類; 任務的結果:介面Future和實現類FutureTask; 任務的執行:核心介面Executor和ExecutorService介面。在Executor框架中有兩個核心類實現了ExecutorService介面,ThreadPoolExecutor和ScheduledThreadPoolExecutor。 # 七、常用執行緒API **1、Fork/Join機制** Fork/Join框架用於並行執行任務,核心的思想就是將一個大任務切分成多個小任務,然後彙總每個小任務的執行結果得到這個大任務的最終結果。核心流程:切分任務,模組任務非同步執行,單任務結果合併。 **2、容器類** ConcurrentHashMap:使用分段鎖機制,把容器中資料分成一段一段的方式儲存,然後給每一段資料配一把鎖,當一個執行緒佔用鎖訪問其中一個段資料的時候,其他段的資料也能被其他執行緒訪問,即考慮安全性也顧及執行效率。 ConcurrentLinkedQueue:基於連結節點的無界執行緒安全佇列,按照FIFO先進先出原則對元素進行排序,佇列的頭部 是佇列中時間最長的元素,佇列的尾部是佇列中時間最短的元素,新的元素新增到佇列的尾部,獲取元素操作從佇列頭部得到。 **3、原子類** JDK自帶原子操作類,處理多個執行緒同時操作一個變數的情況,其中包括:基本型別、陣列型別、引用型別、屬性修改型別。 # 八、應用場景 **1、定時任務** 通過配置設定一些程式在指定時間點,或者週期時間內規律迴圈執行,這裡任務的執行就是基於多執行緒技術。 **2、非同步處理** 非同步處理就是不按照當前同步程式碼塊程式執行,非同步處理與同步處理是對立的,非同步的實現也需要多執行緒或者多程序,提高程式效率。 **3、任務分解** 分散式資料庫中常見操作,資料分佈在不同的資料庫的副本中,在執行查詢時,每個服務都要跑查詢任務,最後在一個服務上做資料合併,或者提供一箇中間引擎層,用來彙總資料,在大型的定時任務中,經常把要處理的任務按照特定策略分片,多個執行緒同時處理。 **4、連線池技術** 建立和管理一個連線的緩衝池的技術,這些連線準備好被任何需要它們的執行緒使用,減少連線不斷建立和釋放的問題,提高程式效率。 # 九、原始碼地址 ``` GitHub·地址 https://github.com/cicadasmile GitEE·地址 https://gitee.com/cicadasmile ``` **推薦閱讀:程式設計體系整理** |序號|專案名稱|GitHub地址|GitEE地址|推薦指數| |:---|:---|:---|:---|:---| |01|Java描述設計模式,演算法,資料結構|[GitHub·點這裡](https://github.com/cicadasmile/model-arithmetic-parent)|[GitEE·點這裡](https://gitee.com/cicadasmile/model-arithmetic-parent)|☆☆☆☆☆| |02|Java基礎、併發、面向物件、Web開發|[GitHub·點這裡](https://github.com/cicadasmile/java-base-parent)|[GitEE·點這裡](https://gitee.com/cicadasmile/java-base-parent)|☆☆☆☆| |03|SpringCloud微服務基礎元件案例詳解|[GitHub·點這裡](https://github.com/cicadasmile/spring-cloud-base)|[GitEE·點這裡](https://gitee.com/cicadasmile/spring-cloud-base)|☆☆☆| |04|SpringCloud微服務架構實戰綜合案例|[GitHub·點這裡](https://github.com/cicadasmile/husky-spring-cloud)|[GitEE·點這裡](https://gitee.com/cicadasmile/husky-spring-cloud)|☆☆☆☆☆| |05|SpringBoot框架基礎應用入門到進階|[GitHub·點這裡](https://github.com/cicadasmile/spring-boot-base)|[GitEE·點這裡](https://gitee.com/cicadasmile/spring-boot-base)|☆☆☆☆| |06|SpringBoot框架整合開發常用中介軟體|[GitHub·點這裡](https://github.com/cicadasmile/middle-ware-parent)|[GitEE·點這裡](https://gitee.com/cicadasmile/middle-ware-parent)|☆☆☆☆☆| |07|資料管理、分散式、架構設計基礎案例|[GitHub·點這裡](https://github.com/cicadasmile/data-manage-parent)|[GitEE·點這裡](https://gitee.com/cicadasmile/data-manage-parent)|☆☆☆☆☆| |08|大資料系列、儲存、元件、計算等框架|[GitHub·點這裡](https://github.com/cicadasmile/big-data-parent)|[GitEE·點這裡](https://gitee.com/cicadasmile/big-data-parent)|☆☆☆☆☆