最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2022年08月26日 09:41:50   作者:記憶的深藍(lán)  
這篇文章主要介紹了Java如何手動創(chuàng)建線程池,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

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

jdk提供了一個通過ThreadPoolExecutor創(chuàng)建一個線程池的類

構(gòu)造器

使用給定的參數(shù)和默認(rèn)的飽和策略、默認(rèn)的工廠方法創(chuàng)建線程池

ThreadPoolExecutor(int corePoolSize,?
int maximumPoolSize,?
long keepAliveTime,?
TimeUnit unit,?
BlockingQueue<Runnable> workQueue)

使用給定的參數(shù)和默認(rèn)的工廠方法創(chuàng)建線程池

ThreadPoolExecutor(int corePoolSize,?
int maximumPoolSize,?
long keepAliveTime,?
TimeUnit unit,?
BlockingQueue<Runnable> workQueue,?
RejectedExecutionHandler handler)

使用給定的參數(shù)和默認(rèn)的飽和策略(AbortPolicy)創(chuàng)建線程池

ThreadPoolExecutor(int corePoolSize,?
int maximumPoolSize,
long keepAliveTime,
BlockingQueue<Runnable> workQueue,?
ThreadFactory threadFactory)

使用指定的參數(shù)創(chuàng)建線程池

ThreadPoolExecutor(int corePoolSize,?
int maximumPoolSize,?
long keepAliveTime,?
TimeUnit unit,
BlockingQueue<Runnable> workQueue,?
RejectedExecutionHandler handler)

參數(shù)說明

  • corePoolSize 線程池的基本大小, 當(dāng)提交一個任務(wù)到線程池的時候,線程池會創(chuàng)建一個線程來執(zhí)行任務(wù),即使當(dāng)前線程池已經(jīng)存在空閑線程,仍然會創(chuàng)建一個線程,等到需要執(zhí)行的任務(wù)數(shù)大于線程池基本大小時就不再創(chuàng)建。如果調(diào)用線程池的prestartAllCoreThreads()方法,線程池會提前創(chuàng)建并啟動所有的基本線程。
  • maximumPoolSizeSize 線程池最大數(shù)量,線程池允許創(chuàng)建的最大線程數(shù),如果隊(duì)列滿了,并且已創(chuàng)建的線程數(shù)小于最大線程數(shù),則線程池會再創(chuàng)建新的線程執(zhí)行任務(wù)。值得注意的是,如果使用了無界的任務(wù)隊(duì)列這個參數(shù)就沒什么效果。
  • keepAliveTime 線程活動保持時間,線程池的工作線程空閑后,保持存活的時間,所以,如果任務(wù)很多,并且每個任務(wù)執(zhí)行的時間比較短,可以調(diào)大時間,提高線程的利用率。
  • unit 線程活動保持時間的單位,可選擇的單位有時分秒等等。
  • workQueue 任務(wù)隊(duì)列。用來暫時保存任務(wù)的工作隊(duì)列
  • threadFactory 用于創(chuàng)建線程的工廠

隊(duì)列

  • ArrayBlockingQueue:是一個基于數(shù)組結(jié)構(gòu)的有界阻塞隊(duì)列,此隊(duì)列按照FIFO(先進(jìn)先出)原則對元素進(jìn)行排序
  • DelayQueue
  • LinkedBlockingDeque
  • LinkedBlockingQueue:是一個基于鏈表結(jié)構(gòu)的有界阻塞隊(duì)列,此隊(duì)列按照FIFO排序元素,吞吐量高于ArrayBlockingQueue。靜態(tài)工廠方法Executors.newFixedThreadPool(n)使用了此隊(duì)列
  • LinkedTransferQueue
  • PriorityBlockingQueue:一個具有優(yōu)先級的無限阻塞隊(duì)列
  • SynchronousQueue:一個不存儲元素的阻塞隊(duì)列。每個插入操作必須等待另一個線程調(diào)用移除操作,否則插入操作一直處于阻塞狀態(tài),吞吐量要高于LinkedBlockingQueue,靜態(tài)工廠方法Executors.newCachedThreadPool()使用了此隊(duì)列

飽和策略

當(dāng)隊(duì)列和線程池都滿了,說明線程池處于飽和的狀態(tài),那么必須采取一種策略處理提交的新任務(wù)。這個策略默認(rèn)是AbortPolicy,表示無法處理新任務(wù)時拋出異常

  • ThreadPoolExecutor.AbortPolicy:直接拋出異常
  • ThreadPoolExecutor.CallerRunsPolicy:只用調(diào)用這所在的線程來運(yùn)行任務(wù)
  • ThreadPoolExecutor.DiscardOldestPolicy:丟棄隊(duì)列里最近的一個任務(wù),并執(zhí)行當(dāng)前任務(wù)
  • ThreadPoolExecutor.DiscardPolicy:不處理,丟棄掉

示例

public class ThreadPool {
? ? /**
? ? ?* 線程池的基本大小
? ? ?*/
? ? static int corePoolSize = 10;
? ? /**
? ? ?* 線程池最大數(shù)量
? ? ?*/
? ? static int maximumPoolSizeSize = 100;
? ? /**
? ? ?* 線程活動保持時間
? ? ?*/
? ? static long keepAliveTime = 1;
? ? /**
? ? ?* 任務(wù)隊(duì)列
? ? ?*/
? ? static ArrayBlockingQueue workQueue = new ArrayBlockingQueue(10);
? ? public static void main(String[] args) {
? ? ? ? ThreadPoolExecutor executor = new ThreadPoolExecutor(
? ? ? ? ? ? ? ? corePoolSize,
? ? ? ? ? ? ? ? maximumPoolSizeSize,
? ? ? ? ? ? ? ? keepAliveTime,
? ? ? ? ? ? ? ? TimeUnit.SECONDS,
? ? ? ? ? ? ? ? workQueue,
? ? ? ? ? ? ? ? new ThreadFactoryBuilder().setNameFormat("XX-task-%d").build());
? ? ? ? //提交一個任務(wù)
? ? ? ? executor.execute(() -> System.out.println("ok"));
? ? }
}

源碼分析

任務(wù)執(zhí)行

public void execute(Runnable command) {
? ? ? ? if (command == null)
? ? ? ? ? ? throw new NullPointerException();
? ? ? ? /*
? ? ? ? ?* Proceed in 3 steps:
? ? ? ? ?*
? ? ? ? ?* 1. If fewer than corePoolSize threads are running, try to
? ? ? ? ?* start a new thread with the given command as its first
? ? ? ? ?* task. ?The call to addWorker atomically checks runState and
? ? ? ? ?* workerCount, and so prevents false alarms that would add
? ? ? ? ?* threads when it shouldn't, by returning false.
? ? ? ? ?*
? ? ? ? ?* 2. If a task can be successfully queued, then we still need
? ? ? ? ?* to double-check whether we should have added a thread
? ? ? ? ?* (because existing ones died since last checking) or that
? ? ? ? ?* the pool shut down since entry into this method. So we
? ? ? ? ?* recheck state and if necessary roll back the enqueuing if
? ? ? ? ?* stopped, or start a new thread if there are none.
? ? ? ? ?*
? ? ? ? ?* 3. If we cannot queue task, then we try to add a new
? ? ? ? ?* thread. ?If it fails, we know we are shut down or saturated
? ? ? ? ?* and so reject the task.
? ? ? ? ?*/
? ? ? ? int c = ctl.get();
? ? ? ? if (workerCountOf(c) < corePoolSize) {
? ? ? ? ? ? if (addWorker(command, true))
? ? ? ? ? ? ? ? return;
? ? ? ? ? ? c = ctl.get();
? ? ? ? }
? ? ? ? if (isRunning(c) && workQueue.offer(command)) {
? ? ? ? ? ? int recheck = ctl.get();
? ? ? ? ? ? if (! isRunning(recheck) && remove(command))
? ? ? ? ? ? ? ? reject(command);
? ? ? ? ? ? else if (workerCountOf(recheck) == 0)
? ? ? ? ? ? ? ? addWorker(null, false);
? ? ? ? }
? ? ? ? else if (!addWorker(command, false))
? ? ? ? ? ? reject(command);
? ? }

參考文檔

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html

線程池工具類

實(shí)現(xiàn)線程的三種方式

1.繼承 Thread 類

2.實(shí)現(xiàn)Runnable 接口

3.實(shí)現(xiàn) Callbale接口和Future接口實(shí)現(xiàn)

4.三種方式比較:

繼承Thread 類 編程簡單,可擴(kuò)展性差。

實(shí)現(xiàn)接口方式 可擴(kuò)展性高,編程復(fù)雜。

使用ThreadPoolExecutor編寫線程池工具類

1.線程創(chuàng)建方式,實(shí)例化賢臣池時,創(chuàng)建核心線程,

2.當(dāng)任務(wù)大于核心線程時將進(jìn)入阻塞隊(duì)列

3.當(dāng)阻塞隊(duì)列滿時,任務(wù)沒有超過最大線程時創(chuàng)建新的線程

4.當(dāng)任務(wù) > 最大線程數(shù)+阻塞隊(duì)列 時,執(zhí)行拒絕策略。 

public class ThreadPoolUtils {
    public static ThreadPoolExecutor pool=null;
    // 無響應(yīng)執(zhí)行
    public static void execute(Runnable runnable){
        getThreadPool().execute(runnable);
    }
    // 有響應(yīng)執(zhí)行
    public static<T> Future<T> submit(Callable<T> callable){
        return getThreadPool().submit(callable);
    }
    // 創(chuàng)造線程池
    private static synchronized ThreadPoolExecutor getThreadPool(){
        if(pool==null){
            // 獲取處理器數(shù)量
            int cpuNum = Runtime.getRuntime().availableProcessors();
            // 根據(jù)cpu數(shù)量,計(jì)算出合理的線程并發(fā)數(shù)
            // 最佳線程數(shù)目 = ((線程等待時間+線程CPU時間)/線程CPU時間 )* CPU數(shù)目
            int maximumPoolSize = cpuNum * 2 + 1;
            // 七個參數(shù)
            // 1. 核心線程數(shù)
            // 2. 最大線程數(shù)
            // 3. 空閑線程最大存活時間
            // 4. 時間單位
            // 5. 阻塞隊(duì)列
            // 6. 創(chuàng)建線程工廠
            // 7. 拒絕策略
            pool=new ThreadPoolExecutor(maximumPoolSize-1,
            maximumPoolSize,
            5,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(50),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());
        }
        return pool;
    }
}

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 淺析Spring中的循環(huán)依賴問題

    淺析Spring中的循環(huán)依賴問題

    這篇文章主要介紹了淺析Spring中的循環(huán)依賴問題,Spring 是利用了 三級緩存 來解決循環(huán)依賴的,其實(shí)現(xiàn)本質(zhì)是通過提前暴露已經(jīng)實(shí)例化但尚未初始化的 bean 來完成的,需要的朋友可以參考下
    2023-11-11
  • Java中String的split切割字符串方法實(shí)例及擴(kuò)展

    Java中String的split切割字符串方法實(shí)例及擴(kuò)展

    最近在項(xiàng)目中遇到一個小問題,一個字符串分割成一個數(shù)組,下面這篇文章主要給大家介紹了關(guān)于Java中String的split切割字符串方法的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • Java實(shí)現(xiàn)ATM取款機(jī)程序

    Java實(shí)現(xiàn)ATM取款機(jī)程序

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)ATM取款機(jī)程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • 快速解決?IDEA?報(bào)錯:?“java?找不到符號“(“cannot?find?symbol“)

    快速解決?IDEA?報(bào)錯:?“java?找不到符號“(“cannot?find?symbol“)

    文章詳細(xì)講解了在IntelliJIDEA中解決“找不到符號”錯誤的方法,包括檢查導(dǎo)入語句、拼寫錯誤、類路徑設(shè)置、文件編譯狀態(tài)、JDK配置以及IDE配置問題,通過具體示例代碼,展示了如何從錯誤代碼到解決步驟,感興趣的朋友一起看看吧
    2025-03-03
  • 關(guān)于Prometheus + Spring Boot 應(yīng)用監(jiān)控的問題

    關(guān)于Prometheus + Spring Boot 應(yīng)用監(jiān)控的問題

    這篇文章主要介紹了關(guān)于Prometheus + Spring Boot 應(yīng)用監(jiān)控的問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • Java讀取.properties配置文件方法示例

    Java讀取.properties配置文件方法示例

    這篇文章主要介紹了Java讀取.properties配置文件,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 解決@RequestBody部分屬性丟失的問題

    解決@RequestBody部分屬性丟失的問題

    這篇文章主要介紹了解決@RequestBody部分屬性丟失的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • SpringBoot實(shí)現(xiàn)發(fā)送郵件、發(fā)送微信公眾號推送功能

    SpringBoot實(shí)現(xiàn)發(fā)送郵件、發(fā)送微信公眾號推送功能

    這篇文章主要介紹了SpringBoot實(shí)現(xiàn)發(fā)送郵件、發(fā)送微信公眾號推送功能,這里對成員變量JavaMailSender使用了@Resource注解,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • Java可以如何實(shí)現(xiàn)文件變動的監(jiān)聽的示例

    Java可以如何實(shí)現(xiàn)文件變動的監(jiān)聽的示例

    本篇文章主要介紹了Java可以如何實(shí)現(xiàn)文件變動的監(jiān)聽的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • SpringBoot多環(huán)境打包與配置文件排除實(shí)踐記錄

    SpringBoot多環(huán)境打包與配置文件排除實(shí)踐記錄

    本文介紹了SpringBoot項(xiàng)目多環(huán)境打包與配置文件排除實(shí)踐,包括多環(huán)境配置的實(shí)現(xiàn)方法、打包時排除配置文件的方法以及動態(tài)加載外部配置文件的最佳實(shí)踐,感興趣的朋友跟隨小編一起看看吧
    2024-11-11

最新評論

友谊县| 同德县| 宝清县| 鱼台县| 文水县| 桂阳县| 修文县| 甘南县| 兴隆县| 永善县| 腾冲县| 洪湖市| 沽源县| 郴州市| 文安县| 青河县| 肇庆市| 家居| 扶绥县| 桂东县| 高雄县| 轮台县| 黄山市| 澄江县| 侯马市| 将乐县| 镇安县| 利川市| 新宁县| 共和县| 台湾省| 平顺县| 林口县| 杭州市| 武川县| 巴林左旗| 中牟县| 新丰县| 萝北县| 金寨县| 澜沧|