偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

面試官:聽(tīng)說(shuō)你很懂線程池?

開(kāi)發(fā) 前端
用Executors工具類,可以很方便地創(chuàng)建各種線程池,它可以創(chuàng)建多種類型的線程池,每種線程池都有不同的特點(diǎn)和適用場(chǎng)景。

什么是線程池

就是一種池化技術(shù),類似的還有jdbc連接池,對(duì)象池。所謂線程池,就是提前創(chuàng)建一堆線程,放到內(nèi)存(池子)中,需要的時(shí)候取一個(gè)出來(lái)用。

如上圖,最頂層的接口就是Executor,實(shí)現(xiàn)ExecutorService接口的類,就是對(duì)應(yīng)的線程池類。

如何創(chuàng)建線程池

用Executors工具類,可以很方便地創(chuàng)建各種線程池。(但是實(shí)際開(kāi)發(fā)我們不推薦,阿里巴巴的開(kāi)發(fā)手冊(cè)嚴(yán)令禁止使用Executors,應(yīng)該用ThreadPoolExecutor)Executors 類可以創(chuàng)建多種類型的線程池,每種線程池都有不同的特點(diǎn)和適用場(chǎng)景。

(1) FixedThreadPool(固定大小線程池):

  • 使用 Executors.newFixedThreadPool(int nThreads) 方法創(chuàng)建。
  • 具有固定大小的線程池,即線程數(shù)量固定不變。
  • 適用于需要控制線程數(shù)量的場(chǎng)景,例如服務(wù)器端處理請(qǐng)求。

(2) CachedThreadPool(緩存線程池):

  • 使用 Executors.newCachedThreadPool() 方法創(chuàng)建。
  • 具有自動(dòng)調(diào)整線程數(shù)量的線程池,根據(jù)需要?jiǎng)?chuàng)建新線程,空閑線程會(huì)被回收。
  • 適用于執(zhí)行大量短期異步任務(wù)的場(chǎng)景,例如異步IO操作。

(3) SingleThreadPool(單線程線程池):

  • 使用 Executors.newSingleThreadExecutor() 方法創(chuàng)建。
  • 只有一個(gè)工作線程的線程池,所有任務(wù)按順序執(zhí)行。
  • 適用于需要保證順序執(zhí)行的任務(wù)場(chǎng)景,例如日志處理。

(4) ScheduledThreadPool(定時(shí)任務(wù)線程池):

  • 使用 Executors.newScheduledThreadPool(int corePoolSize) 方法創(chuàng)建。
  • 具有定時(shí)執(zhí)行任務(wù)的功能,可以按固定的頻率執(zhí)行任務(wù)。
  • 適用于需要定時(shí)執(zhí)行任務(wù)的場(chǎng)景,例如定時(shí)任務(wù)調(diào)度。

(5) WorkStealingPool(工作竊取線程池):

  • 使用 Executors.newWorkStealingPool(int parallelism) 方法創(chuàng)建。
  • 基于ForkJoinPool實(shí)現(xiàn)的線程池,每個(gè)線程都有自己的任務(wù)隊(duì)列,可以竊取其他線程的任務(wù)來(lái)執(zhí)行。
  • 適用于需要處理大量并行任務(wù)的場(chǎng)景,例如并行計(jì)算任務(wù)。

為什么不推薦用Executors創(chuàng)建?

線程池底層原理

我們以ThreadPoolExecutor為例,它是ExecutorService的一種實(shí)現(xiàn)。

一般我們根據(jù)一個(gè)類的構(gòu)造器,可以看出里面的大致思路:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

參數(shù)很多,但是我們每一個(gè)都必須要記住。 這個(gè) ThreadPoolExecutor 的構(gòu)造函數(shù)接受以下參數(shù):一個(gè)線程池就好比一家公司,甲方員工干不完需求的時(shí)候,就要招一些外包人員駐場(chǎng)開(kāi)發(fā),如果活干完了,就讓外包撤場(chǎng),只留下自己的員工。

  • corePoolSize(核心線程數(shù)):線程池中保持活躍的線程數(shù)量,即使它們處于空閑狀態(tài)。當(dāng)提交任務(wù)時(shí),線程池會(huì)嘗試保持至少這么多數(shù)量的線程處于活躍狀態(tài)。 就是公司正式員工的數(shù)量。
  • maximumPoolSize(最大線程數(shù)):線程池中允許的最大線程數(shù)量。當(dāng)任務(wù)隊(duì)列已滿且核心線程都處于活躍狀態(tài)時(shí),線程池會(huì)創(chuàng)建新的線程,直到達(dá)到這個(gè)最大線程數(shù)。 就是公司甲方員工+外包員工的總數(shù),不能超過(guò)這個(gè)數(shù)量。
  • keepAliveTime(線程空閑時(shí)間):非核心線程在空閑狀態(tài)下的最長(zhǎng)存活時(shí)間。超過(guò)這個(gè)時(shí)間,多余的非核心線程將被終止,直到線程數(shù)量不超過(guò)核心線程數(shù)。 如果外包員工長(zhǎng)時(shí)間沒(méi)需求,就通知乙方撤人,裁掉這個(gè)非核心人員。當(dāng)然,甲方爸爸是不會(huì)裁的。
  • unit(時(shí)間單位):用于指定 keepAliveTime 參數(shù)的時(shí)間單位,通常是秒、毫秒、微秒等。
  • workQueue(工作隊(duì)列):用于保存等待執(zhí)行的任務(wù)的阻塞隊(duì)列。當(dāng)所有線程都處于忙碌狀態(tài)時(shí),新提交的任務(wù)會(huì)被放入這個(gè)隊(duì)列中等待執(zhí)行。 當(dāng)需求多到加上外包員工都做不完了,就只能往后排期了。
  • threadFactory(線程工廠):用于創(chuàng)建新線程的工廠。每個(gè)新創(chuàng)建的線程都是通過(guò)這個(gè)工廠創(chuàng)建的。** 就是定義員工的屬性,即工牌,這個(gè)員工屬于哪個(gè)公司的。**
  • handler(拒絕策略):當(dāng)任務(wù)無(wú)法被執(zhí)行時(shí)(通常是由于線程池已關(guān)閉或者任務(wù)隊(duì)列已滿),用于處理被拒絕的任務(wù)的策略。常見(jiàn)的拒絕策略包括拋出異常、丟棄任務(wù)或者在調(diào)用者線程中執(zhí)行任務(wù)。 默認(rèn)是不處理。

這些參數(shù)可以用于配置 ThreadPoolExecutor 對(duì)象,以滿足不同的線程管理需求。

線程池本質(zhì)就是一個(gè)HashSet,所以是無(wú)序的。有新的任務(wù)提交進(jìn)來(lái),如果池子還有線程,就直接拿去處理,池子滿了就放入阻塞隊(duì)列,等待有線程空閑。

線程數(shù)怎么設(shè)置比較合理?

這個(gè)是沒(méi)有銀彈的,我們一般認(rèn)為CPU密集型的應(yīng)用,設(shè)置為CPU核數(shù)N+1。所謂CPU密集型,就是這個(gè)程序計(jì)算量比較多,還比較頻繁,計(jì)算時(shí)間長(zhǎng),也就是所謂的比較吃配置,比如是一個(gè)專門(mén)做算法的服務(wù)(組托,配載運(yùn)算之類的)。

對(duì)于IO密集型的應(yīng)用,設(shè)置為2N+1,什么是IO密集型的應(yīng)用呢,就是提供數(shù)據(jù)服務(wù)比較多,吞吐量比較大,等待時(shí)間長(zhǎng)的應(yīng)用,大部分業(yè)務(wù)系統(tǒng)都屬于此類。

除此之外,線程數(shù)還跟jvm,機(jī)器cpu是否可以超線程(云服務(wù)器一般沒(méi)法超線程),我們看到的cpu核數(shù)一般不是真實(shí)的,所以我們推薦先根據(jù)常規(guī)設(shè)置一個(gè)線程數(shù)量,上線后根據(jù)具體情況再調(diào)整就行了。

責(zé)任編輯:趙寧寧 來(lái)源: java小白翻身
相關(guān)推薦

2025-09-24 17:05:02

2024-09-09 15:09:30

2024-03-11 18:18:58

項(xiàng)目Spring線程池

2025-07-30 00:00:01

優(yōu)先級(jí)線程池排序

2024-09-12 08:35:06

2015-08-13 10:29:12

面試面試官

2025-09-09 00:00:01

2024-10-31 09:30:05

線程池工具Java

2025-02-21 15:25:54

虛擬線程輕量級(jí)

2020-05-22 08:11:48

線程池JVM面試

2021-03-29 08:47:24

線程面試官線程池

2021-05-08 07:53:33

面試線程池系統(tǒng)

2025-09-05 00:00:00

線程池Java并發(fā)編程

2024-09-11 22:51:19

線程通訊Object

2024-05-08 00:00:00

核心線程數(shù)隊(duì)列

2021-11-29 10:55:11

線程池Java面試

2022-06-24 06:43:57

線程池線程復(fù)用

2020-03-10 08:01:05

Java堆內(nèi)存線程共享

2022-07-18 13:59:43

Redis單線程進(jìn)程

2024-06-04 09:02:03

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)