精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Spring 的線程池應(yīng)用

科技綠洲 ? 來(lái)源:Java技術(shù)指北 ? 作者:Java技術(shù)指北 ? 2023-10-13 10:47 ? 次閱讀

我們?cè)谌粘i_發(fā)中,經(jīng)常跟多線程打交道,Spring 為我們提供了一個(gè)線程池方便我們開發(fā),它就是 ThreadPoolTaskExecutor ,接下來(lái)我們就來(lái)聊聊 Spring 的線程池吧。


使用@Async聲明多線程

SpringBoot 提供了注解 @Async 來(lái)使用線程池, 具體使用方法如下:

  1. 在啟動(dòng)類(配置類)添加@EnableAsync來(lái)開啟線程池
  2. 在需要開啟子線程的方法上添加注解 @Async

下面是一個(gè)簡(jiǎn)單的例子:

@Component
@EnableAsync
@EnableScheduling
public class ScheduleTask {

    @Async
    @Scheduled(fixedRate = 2000)
    public void testAsync1() {
        try {
            Thread.sleep(6000);
            System.out.println(LocalDateTime.now() + "--線程1:" + Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Async
    @Scheduled(cron = "*/2 * * * * ?")
    public void testAsync2() {
        try {
            Thread.sleep(1000);
            System.out.println(LocalDateTime.now() + "--線程2:" + Thread.currentThread().getName());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

啟動(dòng)項(xiàng)目,得到如下日志結(jié)果:

圖片

可以發(fā)現(xiàn)在當(dāng)前環(huán)境下 task-${id} 這個(gè) id 并不是一直增長(zhǎng)的,而是一直在復(fù)用 1-8。這個(gè)時(shí)候可能就會(huì)有的小伙伴們會(huì)比較好奇,默認(rèn)的不是 SimpleAsyncTaskExecutor 嗎?為什么從日志打印的效果上看像是一直在復(fù)用 8 個(gè)線程,難道用的是 ThreadPoolTaskExecutor?

原因是 SpringBoot2.1.0 版本后,新增了 TaskExecutionAutoConfiguration 配置類。其中聲明的默認(rèn)線程池就是 ThreadPoolTaskExecutor 。而 @Async 在選擇執(zhí)行器的時(shí)候會(huì)先去 IOC 容器中先找是否有 TaskExecutor 的 Bean對(duì)象,所以在當(dāng)前版本 SpringBoot 中,@Async 的默認(rèn) TaskExecutor 是 ThreadPoolTaskExecutor。

線程池配置

在 SpringBoot 項(xiàng)目中,我們可以在 yaml 或者 properties 配置文件中配置,或者使用 @Configuration 配置,下面演示配置方法。

  1. application.properties配置文件中配置
# 核心線程池?cái)?shù)
spring.task.execution.pool.core-size=5
# 最大線程池?cái)?shù)
spring.task.execution.pool.max-size=10
# 任務(wù)隊(duì)列的容量
spring.task.execution.pool.queue-capacity=5
# 非核心線程的存活時(shí)間
spring.task.execution.pool.keep-alive=60
# 線程池的前綴名稱
spring.task.execution.thread-name-prefix=test-task-
  1. 配置類中配置
@Bean(name = "myThreadPoolTaskExecutor")
public ThreadPoolTaskExecutor getMyThreadPoolTaskExecutor() {
    ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
    int i = Runtime.getRuntime().availableProcessors();
    taskExecutor.setCorePoolSize(i * 2);
    taskExecutor.setMaxPoolSize(i * 2);
    taskExecutor.setQueueCapacity(i * 2 * 100);
    taskExecutor.setKeepAliveSeconds(60);
    taskExecutor.setThreadNamePrefix("my-task-");
    taskExecutor.initialize();
    return taskExecutor;
}

拒絕策略

RejectedExectutionHandler 參數(shù)字段用于配置絕策略,常用拒絕策略如下

  • AbortPolicy:用于被拒絕任務(wù)的處理程序,它將拋出RejectedExecutionException
  • CallerRunsPolicy:用于被拒絕任務(wù)的處理程序,它直接在execute方法的調(diào)用線程中運(yùn)行被拒絕的任務(wù)。
  • DiscardOldestPolicy:用于被拒絕任務(wù)的處理程序,它放棄最舊的未處理請(qǐng)求,然后重試execute。
  • DiscardPolicy:用于被拒絕任務(wù)的處理程序,默認(rèn)情況下它將丟棄被拒絕的任務(wù)。

處理流程

  1. 查看核心線程池是否已滿,不滿就創(chuàng)建一條線程執(zhí)行任務(wù),否則執(zhí)行第2步。
  2. 查看任務(wù)隊(duì)列是否已滿,不滿就將任務(wù)存儲(chǔ)在任務(wù)隊(duì)列中,否則執(zhí)行第3步。
  3. 查看線程池是否已滿,即就是是否達(dá)到最大線程池?cái)?shù),不滿就創(chuàng)建一條線程執(zhí)行任務(wù),否則就按照策略處理無(wú)法執(zhí)行的任務(wù)。

使用注意

  1. 注解的方法必須是 public 方法。
  2. 方法一定要從另一個(gè)類中調(diào)用,也就是從類的外部調(diào)用,類的內(nèi)部調(diào)用是無(wú)效的,因?yàn)?@Transactional 和 @Async 注解的實(shí)現(xiàn)都是基于 Spring 的 AOP ,而 AOP 的實(shí)現(xiàn)是基于動(dòng)態(tài)代理模式實(shí)現(xiàn)的。那么注解失效的原因就很明顯了,有可能因?yàn)檎{(diào)用方法的是對(duì)象本身而不是代理對(duì)象,因?yàn)闆](méi)有經(jīng)過(guò) Spring 容器。
  3. 異步方法使用注解 @Async 的返回值只能為 void 或者 Future。

總結(jié)

上面簡(jiǎn)單介紹了 Spring 自帶的線程池 ThreadPoolTaskExecutor 的配置和使用,并且講了線程池的參數(shù)和處理流程。當(dāng)然Spring提供了7個(gè)線程池的實(shí)現(xiàn),感興趣的可以自行了解~

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 文件
    +關(guān)注

    關(guān)注

    1

    文章

    561

    瀏覽量

    24695
  • 容器
    +關(guān)注

    關(guān)注

    0

    文章

    494

    瀏覽量

    22044
  • spring
    +關(guān)注

    關(guān)注

    0

    文章

    338

    瀏覽量

    14308
  • 線程池
    +關(guān)注

    關(guān)注

    0

    文章

    57

    瀏覽量

    6834
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    跨平臺(tái)的線程組件--TP組件

    /銷毀代價(jià)是很高的。那么我們要怎么去設(shè)計(jì)多線程編程呢???答案:對(duì)于長(zhǎng)駐的線程,我們可以創(chuàng)建獨(dú)立的線程去執(zhí)行。但是非長(zhǎng)駐的線程,我們可以通過(guò)線程
    的頭像 發(fā)表于 04-06 15:39 ?850次閱讀

    Java中的線程包括哪些

    線程是用來(lái)統(tǒng)一管理線程的,在 Java 中創(chuàng)建和銷毀線程都是一件消耗資源的事情,線程可以重復(fù)
    的頭像 發(fā)表于 10-11 15:33 ?784次閱讀
    Java中的<b class='flag-5'>線程</b><b class='flag-5'>池</b>包括哪些

    線程是如何實(shí)現(xiàn)的

    線程的概念是什么?線程是如何實(shí)現(xiàn)的?
    發(fā)表于 02-28 06:20

    基于線程技術(shù)集群接入點(diǎn)的應(yīng)用研究

    本文在深入研究高級(jí)線程技術(shù)的基礎(chǔ)上,分析、研究了固定線程數(shù)目的線程線程數(shù)目動(dòng)態(tài)變化的
    發(fā)表于 01-22 14:21 ?5次下載

    如何正確使用SpringBoot中的線程

    來(lái)自丨CSDN https://blog.csdn.net/m0_37701381/article/details/81072774 使用步驟 先創(chuàng)建一個(gè)線程的配置,讓Spring Boot加載
    的頭像 發(fā)表于 09-02 17:14 ?1990次閱讀

    基于Nacos的簡(jiǎn)單動(dòng)態(tài)化線程實(shí)現(xiàn)

    本文以Nacos作為服務(wù)配置中心,以修改線程核心線程數(shù)、最大線程數(shù)為例,實(shí)現(xiàn)一個(gè)簡(jiǎn)單的動(dòng)態(tài)化線程
    發(fā)表于 01-06 14:14 ?845次閱讀

    線程線程

    線程通常用于服務(wù)器應(yīng)用程序。 每個(gè)傳入請(qǐng)求都將分配給線程池中的一個(gè)線程,因此可以異步處理請(qǐng)求,而不會(huì)占用主線程,也不會(huì)延遲后續(xù)請(qǐng)求的處理
    的頭像 發(fā)表于 02-28 09:53 ?753次閱讀
    多<b class='flag-5'>線程</b>之<b class='flag-5'>線程</b><b class='flag-5'>池</b>

    Java線程核心原理

    看過(guò)Java線程源碼的小伙伴都知道,在Java線程池中最核心的類就是ThreadPoolExecutor,
    的頭像 發(fā)表于 04-21 10:24 ?834次閱讀

    細(xì)數(shù)線程的10個(gè)坑

    JDK開發(fā)者提供了線程的實(shí)現(xiàn)類,我們基于Executors組件,就可以快速創(chuàng)建一個(gè)線程
    的頭像 發(fā)表于 06-16 10:11 ?706次閱讀
    細(xì)數(shù)<b class='flag-5'>線程</b><b class='flag-5'>池</b>的10個(gè)坑

    線程線程怎么釋放

    線程分組看,pool名開頭線程占616條,而且waiting狀態(tài)也是616條,這個(gè)點(diǎn)就非常可疑了,我斷定就是這個(gè)pool開頭線程導(dǎo)致的問(wèn)題。我們先排查為何這個(gè)
    發(fā)表于 07-31 10:49 ?2242次閱讀
    <b class='flag-5'>線程</b><b class='flag-5'>池</b>的<b class='flag-5'>線程</b>怎么釋放

    線程基本概念與原理

    一、線程基本概念與原理 1.1 線程概念及優(yōu)勢(shì) C++線程簡(jiǎn)介
    的頭像 發(fā)表于 11-10 10:24 ?485次閱讀

    線程的基本概念

    線程的基本概念 不管線程是什么東西!但是我們必須知道線程被搞出來(lái)的目的就是:提高程序執(zhí)行效
    的頭像 發(fā)表于 11-10 16:37 ?500次閱讀
    <b class='flag-5'>線程</b><b class='flag-5'>池</b>的基本概念

    線程七大核心參數(shù)執(zhí)行順序

    線程是一種用于管理和調(diào)度線程執(zhí)行的技術(shù),通過(guò)將任務(wù)分配到線程池中的線程進(jìn)行處理,可以有效地控制并發(fā)線程
    的頭像 發(fā)表于 12-04 16:45 ?960次閱讀

    線程的創(chuàng)建方式有幾種

    線程是一種用于管理和調(diào)度線程的技術(shù),能夠有效地提高系統(tǒng)的性能和資源利用率。它通過(guò)預(yù)先創(chuàng)建一組線程并維護(hù)一個(gè)工作隊(duì)列,將任務(wù)提交給線程
    的頭像 發(fā)表于 12-04 16:52 ?826次閱讀

    什么是動(dòng)態(tài)線程?動(dòng)態(tài)線程的簡(jiǎn)單實(shí)現(xiàn)思路

    因此,動(dòng)態(tài)可監(jiān)控線程一種針對(duì)以上痛點(diǎn)開發(fā)的線程管理工具。主要可實(shí)現(xiàn)功能有:提供對(duì) Spring 應(yīng)用內(nèi)
    的頭像 發(fā)表于 02-28 10:42 ?591次閱讀