一. Java 中的線程池是如何實現的
創建一個阻塞隊列來容納任務,在第一次執行任務時創建足夠多的線程,并處理任務,之后每個工作線程自動從任務隊列中獲取線程,直到任務隊列中任務為0為止,此時線程處于等待狀態,一旦有工作任務加入任務隊列中,即刻喚醒工作線程進行處理,實現線程的可復用性。
線程池一般包括四個基本組成部分:
1. 線程池管理器
用于創建線程池,銷毀線程池,添加新任務。
2. 工作線程
線程池中線程,可循環執行任務,在沒有任務時處于等待狀態。
3. 任務隊列
用于存放沒有處理的任務,一種緩存機制。
4. 任務接口
每個任務必須實現的接口,供工作線程調度任務的執行,主要規定了任務的開始和收尾工作,和任務的狀態。
二. 創建線程池的幾個核心構造參數
三. 線程池中的線程是怎么創建的?是一開始就隨著線程池的啟動創建好的嗎?
線程池中的線程是在第一次提交任務submit時創建的
創建線程的方式有繼承Thread和實現Runnable,重寫run方法,start開始執行,wait等待,sleep休眠,shutdown停止。
1. newSingleThreadExecutor:單線程池
顧名思義就是一個池中只有一個線程在運行,該線程永不超時,而且由于是一個線程,當有多個任務需要處理時,會將它們放置到一個無界阻塞隊列中逐個處理,它的實現代碼如下:
它的使用方法也很簡單,下面是簡單的示例:
2. newCachedThreadPool:緩沖功能的線程
建立了一個線程池,而且線程數量是沒有限制的(當然,不能超過Integer的最大值),新增一個任務即有一個線程處理,或者復用之前空閑的線程,或者重親啟動一個線程,但是一旦一個線程在60秒內一直處于等待狀態時(也就是一分鐘無事可做),則會被終止,其源碼如下:
這里需要說明的是,任務隊列使用了同步阻塞隊列,這意味著向隊列中加入一個元素,即可喚醒一個線程(新創建的線程或復用空閑線程來處理),這種隊列已經沒有隊列深度的概念了。
3. newFixedThreadPool:固定線程數量的線程池
在初始化時已經決定了線程的最大數量,若任務添加的能力超出了線程的處理能力,則建立阻塞隊列容納多余的任務,其源碼如下:上面返回的是一個ThreadPoolExecutor,它的corePoolSize和maximumPoolSize是相等的,也就是說,最大線程數量為nThreads。如果任務增長的速度非常快,超過了LinkedBlockingQuene的最大容量(Integer的最大值),那此時會如何處理呢?會按照ThreadPoolExecutor默認的拒絕策略(默認是DiscardPolicy,直接丟棄)來處理。
以上三種線程池執行器都是ThreadPoolExecutor的簡化版,目的是幫助開發人員屏蔽過得線程細節,簡化多線程開發。當需要運行異步任務時,可以直接通過Executors獲得一個線程池,然后運行任務,不需要關注ThreadPoolExecutor的一系列參數時什么含義。當然,有時候這三個線程不能滿足要求,此時則可以直接操作ThreadPoolExecutor來實現復雜的多線程計算。
newSingleThreadExecutor、newCachedThreadPool、newFixedThreadPool是線程池的簡化版,而ThreadPoolExecutor則是旗艦版___簡化版容易操作,需要了解的知識相對少些,方便使用,而旗艦版功能齊全,適用面廣,難以駕馭。
更多關于“Java培訓”的問題,歡迎咨詢千鋒教育在線名師。千鋒已有十余年的培訓經驗,課程大綱更科學更專業,有針對零基礎的就業班,有針對想提升技術的好程序員班,高品質課程助力你實現java程序員夢想。