蘇州怎么制作網(wǎng)頁網(wǎng)站杭州網(wǎng)站seo價格
目錄
前言:
線程池:
線程池的工作流程:
代碼實現(xiàn)線程池:
任務(wù)拒絕策略:?
線程池多大才算合適?
總結(jié):
前言:
????????在Java編程中,線程池是一個強大的工具,它能夠管理和復用線程,提供高效的并發(fā)處理能力。通過線程池,我們可以有效地控制并發(fā)線程的數(shù)量,并降低線程創(chuàng)建和銷毀的開銷。本文將引導你深入了解Java中的線程池,探索其原理、用法和優(yōu)勢,為你提供一個更高效的編程方式。
?
?線程池的作用就是管理線程數(shù)量,減少線程頻繁的創(chuàng)建和銷毀
線程池:
????????線程池是一種用于管理和復用線程的技術(shù),它可以有效地處理并發(fā)任務(wù)并提高程序的性能和響應(yīng)能力。線程池維護著一個線程隊列,其中包含了一定數(shù)量的線程。當有新的任務(wù)到達時,線程池會從隊列中選擇一個空閑的線程來執(zhí)行任務(wù),而不是為每個任務(wù)都創(chuàng)建新的線程。?
線程池的工作流程:
-
創(chuàng)建線程池,包括初始化線程隊列和創(chuàng)建指定數(shù)量的線程。
-
將任務(wù)提交給線程池??梢酝ㄟ^將任務(wù)對象提交給線程池的方式來添加新的任務(wù)。
-
線程池從任務(wù)隊列中選擇一個空閑的線程來執(zhí)行任務(wù)。
-
執(zhí)行任務(wù)。線程池中的線程會執(zhí)行任務(wù)對象中定義的操作。
-
任務(wù)執(zhí)行完成后,線程返回線程池并等待下一個任務(wù)。
-
線程池繼續(xù)從任務(wù)隊列中選擇新的任務(wù)并分配給空閑線程,循環(huán)執(zhí)行以上步驟。
代碼實現(xiàn)線程池:
1.創(chuàng)建線程池的工具類? ?ExecutorService:
- public static ExecutorService newCachedThreadPool()? ? 創(chuàng)建一個沒有上限的線程池
- public static ExecutorService newCachedThreadPool(int int nthread)? ? 創(chuàng)建一個有上限的線程池
其實第一個創(chuàng)建線程池不是真正沒有上限,他的上限是int的最大范圍,只不過因為實在是太大了,因此我們說沒有上限。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPoolExample {public static void main(String[] args) {// 創(chuàng)建一個固定大小為5的線程池ExecutorService threadPool = Executors.newFixedThreadPool(5);// 提交任務(wù)給線程池for (int i = 0; i < 10; i++) {final int taskId = i;threadPool.execute(new Runnable() {public void run() {try {System.out.println("開始執(zhí)行任務(wù):" + taskId);Thread.sleep(2000); // 模擬任務(wù)執(zhí)行時間System.out.println("任務(wù)執(zhí)行完成:" + taskId);} catch (InterruptedException e) {e.printStackTrace();}}});}// 關(guān)閉線程池threadPool.shutdown();}
}
?小技巧:
通過打斷點的方式,我們可以實時看到當前線程池中的線程數(shù)量:
2.自定義創(chuàng)建線程池對象? ThreadPoolExecutor:
在Java中,我們可以使用ThreadPoolExecutor來自定義創(chuàng)建線程池對象。ThreadPoolExecutor是ExecutorService接口的一個實現(xiàn)類,它允許我們靈活地配置線程池的核心線程數(shù)、最大線程數(shù)、線程存活時間等參數(shù)。
首先,我們需要導入java.util.concurrent包。然后,可以通過以下代碼創(chuàng)建一個自定義的線程池對象:
public class test03 {public static void main(String[] args) {ThreadPoolExecutor pool = new ThreadPoolExecutor(3,//核心線程數(shù)量6,//最大線程數(shù)60,//空閑線程最大存活時間TimeUnit.SECONDS,//時間單位new ArrayBlockingQueue<>(3),//指定任務(wù)隊列最大長度Executors.defaultThreadFactory(),//創(chuàng)建線程工廠new ThreadPoolExecutor.AbortPolicy()//任務(wù)的拒絕策略);}
}
在上述代碼中,我們傳入了核心線程數(shù)、最大線程數(shù)、非核心線程空閑超時時間以及任務(wù)隊列等參數(shù)來創(chuàng)建線程池對象。你還可以根據(jù)需要,調(diào)整這些參數(shù)以滿足你的實際需求。
核心線程數(shù)(corePoolSize):核心線程數(shù)是線程池中一直存活的線程數(shù)量。當提交一個任務(wù)時,如果當前核心線程數(shù)還未達到設(shè)定的值,線程池會創(chuàng)建新的核心線程來處理任務(wù)。即使核心線程處于空閑狀態(tài),它們也不會被回收。
最大線程數(shù)(maxPoolSize):最大線程數(shù)是線程池中能容納的最大線程數(shù)量。當提交的任務(wù)超過了核心線程數(shù)并且任務(wù)隊列已滿時,線程池會創(chuàng)建新的線程來執(zhí)行任務(wù),直到達到最大線程數(shù)。超過最大線程數(shù)的任務(wù)將會被拒絕執(zhí)行。
非核心線程空閑超時時間(keepAliveTime):當線程池中的線程數(shù)量超過核心線程數(shù),并且這些線程處于空閑狀態(tài)時,非核心線程會被回收。空閑超時時間設(shè)定了非核心線程的最長存活時間,超過這個時間,空閑的非核心線程將被回收。
任務(wù)拒絕策略:?
在Java中,任務(wù)拒絕策略用于處理線程池無法接受更多任務(wù)時的行為。當線程池已滿并且工作隊列已滿或達到最大容量時,新提交的任務(wù)可能會被拒絕執(zhí)行。Java提供了四種默認的任務(wù)拒絕策略:
-
AbortPolicy(中止策略):這是默認的任務(wù)拒絕策略。當線程池無法接受新任務(wù)時,新提交的任務(wù)會立即拋出RejectedExecutionException異常。
-
CallerRunsPolicy(調(diào)用者運行策略):如果線程池無法接受新任務(wù),則由提交任務(wù)的線程來執(zhí)行該任務(wù)。這意味著任務(wù)的執(zhí)行將回退到調(diào)用線程中執(zhí)行,從而降低了整體的并發(fā)度。
-
DiscardPolicy(丟棄策略):當線程池無法接受新任務(wù)時,新提交的任務(wù)將被靜默丟棄,不會拋出任何異常。這意味著被丟棄的任務(wù)將不會被執(zhí)行。
-
DiscardOldestPolicy(丟棄最舊策略):當線程池無法接受新任務(wù)時,線程池會丟棄工作隊列中最舊的任務(wù)(即最先提交的任務(wù)),然后嘗試再次提交新任務(wù)。
除了這四種默認的拒絕策略外,還可以通過實現(xiàn)RejectedExecutionHandler接口來自定義任務(wù)拒絕策略。通過實現(xiàn)該接口,可以定義自己的拒絕策略邏輯,例如將被拒絕的任務(wù)記錄下來或?qū)⑵浞湃肫渌犃兄械?。然?#xff0c;可以將自定義的拒絕策略傳遞給線程
在自定義線程池中,我們需要掌握好自定義過程中的七個參數(shù)的意義。
線程池多大才算合適?
線程池大小的計算是有計算公式的,在介紹計算公式之前,我們要先講解一下什么是最大并行數(shù)
最大并行數(shù)指的是在給定的系統(tǒng)環(huán)境下同時執(zhí)行的最大線程或任務(wù)數(shù)。
線程池大小計算公式:?
1.CPU密集型運算:
????????在CPU密集型運算中,任務(wù)主要是由CPU執(zhí)行,涉及較少的I/O操作。在這種情況下,線程池的大小可以通過以下公式計算:
最大并行數(shù)+1
2.I/O密集型運算:
????????在I/O密集型運算中,任務(wù)涉及大量的I/O操作,例如讀取文件、網(wǎng)絡(luò)通信等。在這種情況下,由于任務(wù)執(zhí)行時間中有很多時間被阻塞在I/O等待上,可以通過以下公式計算線程池的大小:
Nthreads = Ncpu * Ucpu * (1 + (W/C))
Nthreads
?是線程池中的線程數(shù)。Ncpu
?是計算機中的CPU核心數(shù)。Ucpu
?是期望的CPU利用率(0 <= Ucpu <= 1)。它表示期望的CPU工作時間與總時間的比例。W/C
?通常設(shè)置為較大的值,以便在I/O等待期間可以讓CPU執(zhí)行其他任務(wù)。
在I/O密集型任務(wù)中,通過增加線程池的大小可以更好地利用I/O等待的時間,提高整體的并發(fā)性能。然而,過量的線程數(shù)也會增加上下文切換的開銷,因此需要根據(jù)實
總結(jié):
? ? ? ? 今天我們學習了線程池的使用,學習了調(diào)用庫類實現(xiàn)線程池以及自定義線程池。而多線程的內(nèi)容其實并沒有介紹完畢,我們將會在后面詳細的介紹線程中比較重要的樂觀鎖以及悲觀鎖,還有大名鼎鼎的CAS算法。
如果我的內(nèi)容對你有幫助,請點贊,評論,收藏。創(chuàng)作不易,大家的支持就是我堅持下去的動力!