ThreadPoolTaskExecutor小記

  • corePoolSize(核心線程數(shù))

    • 核心線程會一直存在择镇,即使沒有任務(wù)執(zhí)行娇斩;
    • 當線程數(shù)小于核心線程數(shù)的時候部念,即使有空閑線程,也會一直創(chuàng)建線程直到達到核心線程數(shù)土榴;
    • 設(shè)置allowCoreThreadTimeout=true(默認false)時诀姚,核心線程會超時關(guān)閉。
  • queueCapacity(任務(wù)隊列容量)

    • 也叫阻塞隊列玷禽,當核心線程都在運行赫段,此時再有任務(wù)進來,會進入任務(wù)隊列矢赁,排隊等待線程執(zhí)行糯笙。
  • maxPoolSize(最大線程數(shù))

    • 線程池里允許存在的最大線程數(shù)量;
    • 當任務(wù)隊列已滿撩银,且線程數(shù)量大于等于核心線程數(shù)時给涕,會創(chuàng)建新的線程執(zhí)行任務(wù);
    • 線程池里允許存在的最大線程數(shù)量额获。當任務(wù)隊列已滿够庙,且線程數(shù)量大于等于核心線程數(shù)時,會創(chuàng)建新的線程執(zhí)行任務(wù)抄邀。
  • keepAliveTime(線程空閑時間)

    • 當線程空閑時間達到keepAliveTime時耘眨,線程會退出(關(guān)閉),直到線程數(shù)等于核心線程數(shù)境肾;
    • 如果設(shè)置了allowCoreThreadTimeout=true剔难,則線程會退出直到線程數(shù)等于零胆屿。
    • allowCoreThreadTimeout(允許核心線程超時)
    • ejectedExecutionHandler(任務(wù)拒絕處理器)
    • 當線程數(shù)量達到最大線程數(shù),且任務(wù)隊列已滿時,會拒絕任務(wù);
    • 調(diào)用線程池shutdown()方法后吱肌,會等待執(zhí)行完線程池的任務(wù)之后奔垦,再shutdown()。如果在調(diào)用了shutdown()方法和線程池真正shutdown()之間提交任務(wù)砰识,會拒絕新任務(wù)。
  • 任務(wù)執(zhí)行解析

    • 如果線程池中線程數(shù)量 < 核心線程數(shù),新建一個線程執(zhí)行任務(wù)唇兑;
    • 如果線程池中線程數(shù)量 >= 核心線程數(shù),則將任務(wù)放入任務(wù)隊列
    • 如果線程池中線程數(shù)量 >= 核心線程數(shù) 且 < maxPoolSize,且任務(wù)隊列滿了桦锄,則創(chuàng)建新的線程扎附;
    • 如果線程池中線程數(shù)量 > 核心線程數(shù),當線程空閑時間超過了keepalive時,則會銷毀線程结耀;由此可見線程池的隊列如果是無界隊列留夜,那么設(shè)置線程池最大數(shù)量是無效的;
    • 如果線程池中的任務(wù)隊列滿了图甜,而且線程數(shù)達到了maxPoolSize碍粥,并且沒有空閑的線程可以執(zhí)行新的任務(wù),這時候再提交任務(wù)就會執(zhí)行拒絕策略
  • rejectedExecutionHandler字段用于配置拒絕策略黑毅,常用的拒絕策略如下:

    • AbortPolicy 拋出RejectedExecutionException嚼摩。
    • CallerRunsPolicy 直接在execute方法的調(diào)用線程中運行被拒絕的任務(wù)。
    • DiscardOldestPolicy 放棄最舊的未處理請求矿瘦,然后重試execute枕面。
    • DiscardPolicy 下它將丟棄被拒絕的任務(wù)。

Spring Boot中異步線程池的配置

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@Slf4j
@Configuration
public class AsyncExecutorConfig {

    @Bean
    public Executor asyncServiceExecutor() {
        log.info("start asyncServiceExecutor");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //配置核心線程數(shù)
        //如果是IO密集型應用缚去,則線程池大小設(shè)置為2N+1潮秘;
        //如果是CPU密集型應用,則線程池大小設(shè)置為N+1易结;
        executor.setCorePoolSize(6);
        //配置最大線程數(shù)
        executor.setMaxPoolSize(10);
        //配置隊列大小
        executor.setQueueCapacity(10000);
        //配置線程池中的線程的名稱前綴
        executor.setThreadNamePrefix("async-service-");
        // 設(shè)置拒絕策略:當pool已經(jīng)達到max size的時候唇跨,如何處理新任務(wù)
        // CALLER_RUNS:不在新線程中執(zhí)行任務(wù),而是有調(diào)用者所在的線程來執(zhí)行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //執(zhí)行初始化
        executor.initialize();
        return executor;
    }
}

異步使用方法

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class AsyncService {

    @Async("asyncServiceExecutor")
    public Future<String> getAsyncResult1() {
        String result = "asyncResultTest1";
        try {
            Thread.sleep(3000);
            log.info("線程名稱:{}衬衬,睡眠:{}秒", Thread.currentThread().getName(), "3");

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return new AsyncResult<String>(result);
    }

    @Async("asyncServiceExecutor")
    public Future<String> getAsyncResult2() {
        String result = "asyncResultTest2";
        try {
            Thread.sleep(4000);
            log.info("線程名稱:{}买猖,睡眠:{}秒", Thread.currentThread().getName(), "4");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return new AsyncResult<String>(result);
    }
}
@RestController
@RequestMapping(value = "/test")
public class TestController extends BaseBeanController {

     //線程池,上面Config中定義的
    @Autowired
    public Executor asyncServiceExecutor;
    @PostMapping(value = "/test")
    public DeferredResult<R> test() throws ExecutionException, InterruptedException {
        DeferredResult deferredResult = new DeferredResult(10000L);
        CompletableFuture<R> result = CompletableFuture.supplyAsync(() -> {
            //耗時方法
        }, asyncServiceExecutor);
        deferredResult.setResult(result.get());
        return deferredResult;
    }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末滋尉,一起剝皮案震驚了整個濱河市玉控,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌狮惜,老刑警劉巖高诺,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件碌识,死亡現(xiàn)場離奇詭異,居然都是意外死亡虱而,警方通過查閱死者的電腦和手機筏餐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來牡拇,“玉大人魁瞪,你說我怎么就攤上這事』莺簦” “怎么了导俘?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長剔蹋。 經(jīng)常有香客問我旅薄,道長,這世上最難降的妖魔是什么泣崩? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任少梁,我火速辦了婚禮,結(jié)果婚禮上矫付,老公的妹妹穿的比我還像新娘凯沪。我一直安慰自己,他們只是感情好技即,可當我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著樟遣,像睡著了一般而叼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上豹悬,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天葵陵,我揣著相機與錄音,去河邊找鬼瞻佛。 笑死脱篙,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的伤柄。 我是一名探鬼主播绊困,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼适刀!你這毒婦竟也來了秤朗?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤笔喉,失蹤者是張志新(化名)和其女友劉穎取视,沒想到半個月后硝皂,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡作谭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年稽物,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片折欠。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡贝或,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出怨酝,到底是詐尸還是另有隱情傀缩,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布农猬,位于F島的核電站赡艰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏斤葱。R本人自食惡果不足惜慷垮,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望揍堕。 院中可真熱鬧料身,春花似錦、人聲如沸衩茸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽楞慈。三九已至幔烛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間囊蓝,已是汗流浹背饿悬。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留聚霜,地道東北人狡恬。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像蝎宇,于是被迫代替她去往敵國和親弟劲。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容

  • 原文出處http://cmsblogs.com/ 『chenssy』 作為Executor框架中最核心的類姥芥,Thr...
    踩在浪花上看浪閱讀 1,221評論 0 4
  • 深入分析線程池 在前面的文章中函卒,我們使用線程的時候就去創(chuàng)建一個線程,這樣實現(xiàn)起來非常簡便,但是就會有一個問題: 如...
    史路比閱讀 447評論 0 1
  • 線程池中有一定數(shù)量的工作線程报嵌,工作線程會循環(huán)從任務(wù)隊列中獲取任務(wù)虱咧,并執(zhí)行這個任務(wù)。那么怎么去停止這些工作線程呢锚国?這...
    wo883721閱讀 1,593評論 0 14
  • 曾幾何時血筑,童年的小伙伴與我們漸行漸遠绘沉,或許有的人說,我的童年不幸福豺总,我就是要忘記童年的悲痛车伞,為何要讓我再回憶當初的...
    筆墨傳情閱讀 591評論 0 0
  • 剛送走姑娘上學,再給孩子洗校服喻喳,孩子每天的陪伴和守護在身邊另玖,覺得生活過的挺充實。做人你太忍讓每一個人表伦,不但不尊重你...
    堅強的玫瑰花閱讀 101評論 1 1