溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java線程池怎么用

發(fā)布時(shí)間:2021-05-31 10:03:03 來(lái)源:億速云 閱讀:131 作者:小新 欄目:開(kāi)發(fā)技術(shù)

小編給大家分享一下Java線程池怎么用,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

一、什么是線程池?

線程池是一種用于實(shí)現(xiàn)計(jì)算機(jī)程序并發(fā)執(zhí)行的軟件設(shè)計(jì)模式。線程池維護(hù)多個(gè)線程,等待由調(diào)度程序分配任務(wù)以并發(fā)執(zhí)行,該模型提高了性能,并避免了由于為短期任務(wù)頻繁創(chuàng)建和銷毀線程而導(dǎo)致的執(zhí)行延遲。

二、線程池要解決什么問(wèn)題?

說(shuō)到線程池就一定要從線程的生命周期講起。

Java線程池怎么用

從圖中可以了解無(wú)論任務(wù)執(zhí)行多久,每個(gè)線程都要經(jīng)歷從生到死的狀態(tài)。而使用線程池就是為了避免線程的重復(fù)創(chuàng)建,從而節(jié)省了線程的NewRunnable, RunningTerminated的時(shí)間;同時(shí)也會(huì)復(fù)用線程,最小化的節(jié)省系統(tǒng)資源,于此同時(shí)提高了響應(yīng)速度。

三、線程池的使用

線程池的創(chuàng)建

使用ThreadPoolExecutor并配置7個(gè)參數(shù)完成線程池的創(chuàng)建

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)
  • corePoolSize:線程池中核心線程的最大值

  • maximumPoolSize:線程池中最大線程數(shù)

  • keepAliveTime:非核心線程空閑的存活時(shí)間大小

  • unit:keepAliveTime的單位,常用的有秒、分鐘、小時(shí)等

  • workQueue:阻塞隊(duì)列類型

  • threadFactory:線程工廠,用于配置線程的名稱,是否為守護(hù)線程等

  • handler:線程池的拒絕策略

四、常用阻塞隊(duì)列

ArrayBlockingQueue

底層基于數(shù)組的實(shí)現(xiàn)的有界阻塞隊(duì)列

LinkedBlockingQueue

底層基于單鏈表的阻塞隊(duì)列,可配置容量,不配置容量默認(rèn)為Integer.MAX_VALUE

五、線程工廠

在《阿里巴巴Java開(kāi)發(fā)手冊(cè)》中強(qiáng)制要求指定線程的名稱

Java線程池怎么用

由于工作是使用hutool比較多,里面也包含對(duì)ThreadFactory的封裝,可以很方便的指定名稱

ThreadFactory threadFactory = ThreadFactoryBuilder.create().setNamePrefix("myThread-").build();

六、拒絕策略

當(dāng)線程池內(nèi)工作線程數(shù)大于maximumPoolSize時(shí),線程就不再接受任務(wù),執(zhí)行對(duì)應(yīng)的拒絕策略;目前支持的拒絕策略有四種:

1.AbortPolicy(默認(rèn)):丟棄任務(wù)并拋出RejectedExecutionException異常

2.CallerRunsPolicy:由調(diào)用者處理

3.DiscardOldestPolicy:丟棄隊(duì)列中最前面的任務(wù),并重新入隊(duì)列

4.DiscardPolicy:丟棄任務(wù)但不拋出異常

七、線程池的執(zhí)行邏輯

// 創(chuàng)建線程工廠
ThreadFactory threadFactory = ThreadFactoryBuilder.create().setNamePrefix("myThread-").build();
// 創(chuàng)建線程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), threadFactory, new ThreadPoolExecutor.AbortPolicy());

八、execute()方法

// 組合值;保存了線程池的工作狀態(tài)和工作線程數(shù)
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
public void execute(Runnable command) {
    	// 任務(wù)為空 拋出NPE
        if (command == null)
            throw new NullPointerException();
        // 獲取線程池狀態(tài)
        int c = ctl.get();
        // 如果工作線程數(shù)小于核心線程數(shù)就創(chuàng)建新線程
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        // 如果線程池處于Running狀態(tài),就把任務(wù)放在隊(duì)列尾部
        if (isRunning(c) && workQueue.offer(command)) {
            // 重新檢查線程池狀態(tài)
            int recheck = ctl.get();
            // 如果線程池不是Running狀態(tài),就移除剛才添加的任務(wù),并執(zhí)行拒絕策略
            if (! isRunning(recheck) && remove(command))
                reject(command);
            // 是Running狀態(tài),就添加線程
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        // 添加任務(wù)失敗,執(zhí)行拒絕策略
        else if (!addWorker(command, false))
            reject(command);
    }
// addWorker()完成線程的創(chuàng)建

九、執(zhí)行流程

Java線程池怎么用

以上是“Java線程池怎么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI