java多線程經驗總結(JAVA拾遺系列之JAVA基礎-多線程)
2023-05-14 23:01:32
java多線程經驗總結?要了解多線程,需要了解相關的基礎知識,接下來我們就來聊聊關於java多線程經驗總結?以下內容大家不妨參考一二希望能幫到您!
java多線程經驗總結
一、概述要了解多線程,需要了解相關的基礎知識。
在計算機作業系統中,進程管理也稱為處理機管理,其核心是如何合理地分配處理機的時間,提高系統的效率。在計算機系統中有多個並發執行的程序,採用程序這個靜態概念已經不能描述程序執行時動態變化的過程,所以引入了進程。
進程是程序的一次執行。進程通常由程序、數據和進程控制塊組成。進程的三態模型指的是運行、就緒、阻塞,進程的五態模型指的是新建、就緒、運行、阻塞、終止。
由於進程的創建、撤銷和切換中,系統必須為之付出較大的時空開銷,因此在系統中設置的進程數目不宜過多,進程切換的頻率不宜太高,這就限制了並發程序的提高。引入線程後,將傳統進程的兩個基本屬性分開,線程作為調度和分配的基本單位,進程作為獨立分配資源的單位。線程基本上不擁有資源,只擁有一點運行時必不可少的資源(如程序計數器、一組寄存器和棧)。
二、JAVA線程池合理使用線程池有利於提高線程的復用性,從而提高系統的運行效率。Java提供ThreadPoolExecutor來創建不同場景下的線程池,主要分為四類:
1、newCachedThreadPool創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閒線程,若無可回收,則新建線程。2、newFixedThreadPool 創建一個定長線程池,可控制線程最大並發數,超出的線程會在隊列中等待。3、newScheduledThreadPool 創建一個定長線程池,支持定時及周期性任務執行。4、newSingleThreadExecutor 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。
無論創建哪種線程池,都有同樣的參數,主要是:
1、corePoolSize,核心線程數,也就是同時運行的線程數
2、maximumPoolSize,最大容納的線程數量,超過數量之後,有幾種策略,詳見handler參數
3、keepAliveTime,線程的生命時長
4、unit,與keepAliveTime對應代表時間的單位
5、workQueue,隊列
6、handler,提交線程數量大於maximumPoolSize時的處理器,有四種處理方式:1、AbortPolicy,拋出異常給調用者;2、CallerRunsPolicy,在調用者所在線程執行;3、DiscardOldestPolicy,拋棄等待隊列中等待最長的那個任務,並把這個任務加入到隊列;4、DiscardPolicy,拋棄任務。
7、threadFactory,線程創建工廠
ThreadPoolExecutor有幾個核心的方法:
1、execute:執行任務
2、getCorePoolSize:獲取普通運行時線程數量上限
3、getPoolSize:獲取當前線程池數量
4、getQueue:獲取等待隊列
5、getActiveCount:獲取正在執行的線程數量(估計值)
三、JAVA線程鎖當對數據修改時,如果兩個線程同時去修改同一條數據,這樣產生的結果就不是我們預期的結果。這時候就需要對修改操作進行加鎖,讓jvm裡同一時刻只能有一個線程能夠執行修改方法。在Java中,java.util.concurrent.locks包下的ReentrantLock可以很方便的實現加鎖和釋放鎖。示例代碼如下:
class X { private final ReentrantLock lock = new ReentrantLock; // ... public void m { lock.lock; // block until condition holds try { // ... method body } finally { lock.unlock } } }
四、分布式鎖基本思路當在微服務中,同一個服務可能部署多個示例,這樣同樣的代碼加鎖就變得沒有任何意義。所以引入了分布式鎖,分布式鎖核心原理是藉助第三方中間件,如Reids,存儲一個標識:
1、當執行加鎖代碼時,檢查是否存在標識;
2、如果存在,表示其它線程正在執行;
3、如果不存在表示沒有線程正在執行,可以進行加鎖。
,