色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何正確使用SpringBoot中的線程池

Android編程精選 ? 來源:CSDN博客 ? 作者:如漩渦 ? 2021-09-02 17:14 ? 次閱讀

來自丨CSDN

https://blog.csdn.net/m0_37701381/article/details/81072774

使用步驟

先創建一個線程池的配置,讓Spring Boot加載,用來定義如何創建一個ThreadPoolTaskExecutor,要使用@Configuration和@EnableAsync這兩個注解,表示這是個配置類,并且是線程池的配置類

@Configuration@EnableAsyncpublic class ExecutorConfig {

private static final Logger logger = LoggerFactory.getLogger(ExecutorConfig.class);

@Value(“${async.executor.thread.core_pool_size}”)

private int corePoolSize;

@Value(“${async.executor.thread.max_pool_size}”)

private int maxPoolSize;

@Value(“${async.executor.thread.queue_capacity}”)

private int queueCapacity;

@Value(“${async.executor.thread.name.prefix}”)

private String namePrefix;

@Bean(name = “asyncServiceExecutor”)

public Executor asyncServiceExecutor() {

logger.info(“start asyncServiceExecutor”);

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

//配置核心線程數

executor.setCorePoolSize(corePoolSize);

//配置最大線程數

executor.setMaxPoolSize(maxPoolSize);

//配置隊列大小

executor.setQueueCapacity(queueCapacity);

//配置線程池中的線程的名稱前綴

executor.setThreadNamePrefix(namePrefix);

// rejection-policy:當pool已經達到max size的時候,如何處理新任務

// CALLER_RUNS:不在新線程中執行任務,而是有調用者所在的線程來執行

executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

//執行初始化

executor.initialize();

return executor;

}

}

@Value是我配置在application.properties,可以參考配置,自由定義

# 異步線程配置# 配置核心線程數

async.executor.thread.core_pool_size = 5

# 配置最大線程數

async.executor.thread.max_pool_size = 5

# 配置隊列大小

async.executor.thread.queue_capacity = 99999

# 配置線程池中的線程的名稱前綴

async.executor.thread.name.prefix = async-service-

創建一個Service接口,是異步線程的接口

public interface AsyncService {

/**

* 執行異步任務

* 可以根據需求,自己加參數擬定,我這里就做個測試演示

*/

void executeAsync();

}

實現類

@Servicepublic class AsyncServiceImpl implements AsyncService {

private static final Logger logger = LoggerFactory.getLogger(AsyncServiceImpl.class);

@Override

@Async(“asyncServiceExecutor”)

public void executeAsync() {

logger.info(“start executeAsync”);

System.out.println(“異步線程要做的事情”);

System.out.println(“可以在這里執行批量插入等耗時的事情”);

logger.info(“end executeAsync”);

}

}

將Service層的服務異步化,在executeAsync()方法上增加注解@Async(“asyncServiceExecutor”),asyncServiceExecutor方法是前面ExecutorConfig.java中的方法名,表明executeAsync方法進入的線程池是asyncServiceExecutor方法創建的。

接下來就是在Controller里或者是哪里通過注解@Autowired注入這個Service

@Autowiredprivate AsyncService asyncService;

@GetMapping(“/async”)

public void async(){

asyncService.executeAsync();

}

用postmain或者其他工具來多次測試請求一下

2018-07-16 2247.655 INFO 10516 --- [async-service-5] c.u.d.e.executor.impl.AsyncServiceImpl : start executeAsync

異步線程要做的事情

可以在這里執行批量插入等耗時的事情

2018-07-16 2247.655 INFO 10516 --- [async-service-5] c.u.d.e.executor.impl.AsyncServiceImpl : end executeAsync

2018-07-16 2247.770 INFO 10516 --- [async-service-1] c.u.d.e.executor.impl.AsyncServiceImpl : start executeAsync

異步線程要做的事情

可以在這里執行批量插入等耗時的事情

2018-07-16 2247.770 INFO 10516 --- [async-service-1] c.u.d.e.executor.impl.AsyncServiceImpl : end executeAsync

2018-07-16 2247.816 INFO 10516 --- [async-service-2] c.u.d.e.executor.impl.AsyncServiceImpl : start executeAsync

異步線程要做的事情

可以在這里執行批量插入等耗時的事情

2018-07-16 2247.816 INFO 10516 --- [async-service-2] c.u.d.e.executor.impl.AsyncServiceImpl : end executeAsync

2018-07-16 2248.833 INFO 10516 --- [async-service-3] c.u.d.e.executor.impl.AsyncServiceImpl : start executeAsync

異步線程要做的事情

可以在這里執行批量插入等耗時的事情

2018-07-16 2248.834 INFO 10516 --- [async-service-3] c.u.d.e.executor.impl.AsyncServiceImpl : end executeAsync

2018-07-16 2248.986 INFO 10516 --- [async-service-4] c.u.d.e.executor.impl.AsyncServiceImpl : start executeAsync

異步線程要做的事情

可以在這里執行批量插入等耗時的事情

2018-07-16 2248.987 INFO 10516 --- [async-service-4] c.u.d.e.executor.impl.AsyncServiceImpl : end executeAsync

通過以上日志可以發現,[async-service-]是有多個線程的,顯然已經在我們配置的線程池中執行了,并且每次請求中,controller的起始和結束日志都是連續打印的,表明每次請求都快速響應了,而耗時的操作都留給線程池中的線程去異步執行;

雖然我們已經用上了線程池,但是還不清楚線程池當時的情況,有多少線程在執行,多少在隊列中等待呢?這里我創建了一個ThreadPoolTaskExecutor的子類,在每次提交線程的時候都會將當前線程池的運行狀況打印出來

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import org.springframework.util.concurrent.ListenableFuture;

import java.util.concurrent.Callable;

import java.util.concurrent.Future;

import java.util.concurrent.ThreadPoolExecutor;

/**

* @Author: ChenBin

*/public class VisiableThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {

private static final Logger logger = LoggerFactory.getLogger(VisiableThreadPoolTaskExecutor.class);

private void showThreadPoolInfo(String prefix) {

ThreadPoolExecutor threadPoolExecutor = getThreadPoolExecutor();

if (null == threadPoolExecutor) {

return;

}

logger.info(“{}, {},taskCount [{}], completedTaskCount [{}], activeCount [{}], queueSize [{}]”,

this.getThreadNamePrefix(),

prefix,

threadPoolExecutor.getTaskCount(),

threadPoolExecutor.getCompletedTaskCount(),

threadPoolExecutor.getActiveCount(),

threadPoolExecutor.getQueue().size());

}

@Override

public void execute(Runnable task) {

showThreadPoolInfo(“1. do execute”);

super.execute(task);

}

@Override

public void execute(Runnable task, long startTimeout) {

showThreadPoolInfo(“2. do execute”);

super.execute(task, startTimeout);

}

@Override

public Future《?》 submit(Runnable task) {

showThreadPoolInfo(“1. do submit”);

return super.submit(task);

}

@Override

public 《T》 Future《T》 submit(Callable《T》 task) {

showThreadPoolInfo(“2. do submit”);

return super.submit(task);

}

@Override

public ListenableFuture《?》 submitListenable(Runnable task) {

showThreadPoolInfo(“1. do submitListenable”);

return super.submitListenable(task);

}

@Override

public 《T》 ListenableFuture《T》 submitListenable(Callable《T》 task) {

showThreadPoolInfo(“2. do submitListenable”);

return super.submitListenable(task);

}

}

如上所示,showThreadPoolInfo方法中將任務總數、已完成數、活躍線程數,隊列大小都打印出來了,然后Override了父類的execute、submit等方法,在里面調用showThreadPoolInfo方法,這樣每次有任務被提交到線程池的時候,都會將當前線程池的基本情況打印到日志中;

修改ExecutorConfig.java的asyncServiceExecutor方法,將ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor()改為ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor()

@Bean(name = “asyncServiceExecutor”)

public Executor asyncServiceExecutor() {

logger.info(“start asyncServiceExecutor”);

//在這里修改

ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor();

//配置核心線程數

executor.setCorePoolSize(corePoolSize);

//配置最大線程數

executor.setMaxPoolSize(maxPoolSize);

//配置隊列大小

executor.setQueueCapacity(queueCapacity);

//配置線程池中的線程的名稱前綴

executor.setThreadNamePrefix(namePrefix);

// rejection-policy:當pool已經達到max size的時候,如何處理新任務

// CALLER_RUNS:不在新線程中執行任務,而是有調用者所在的線程來執行

executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

//執行初始化

executor.initialize();

return executor;

}

再次啟動該工程測試

2018-07-16 2230.951 INFO 14088 --- [nio-8087-exec-2] u.d.e.e.i.VisiableThreadPoolTaskExecutor : async-service-, 2. do submit,taskCount [0], completedTaskCount [0], activeCount [0], queueSize [0]

2018-07-16 2230.952 INFO 14088 --- [async-service-1] c.u.d.e.executor.impl.AsyncServiceImpl : start executeAsync

異步線程要做的事情

可以在這里執行批量插入等耗時的事情

2018-07-16 2230.953 INFO 14088 --- [async-service-1] c.u.d.e.executor.impl.AsyncServiceImpl : end executeAsync

2018-07-16 2231.351 INFO 14088 --- [nio-8087-exec-3] u.d.e.e.i.VisiableThreadPoolTaskExecutor : async-service-, 2. do submit,taskCount [1], completedTaskCount [1], activeCount [0], queueSize [0]

2018-07-16 2231.353 INFO 14088 --- [async-service-2] c.u.d.e.executor.impl.AsyncServiceImpl : start executeAsync

異步線程要做的事情

可以在這里執行批量插入等耗時的事情

2018-07-16 2231.353 INFO 14088 --- [async-service-2] c.u.d.e.executor.impl.AsyncServiceImpl : end executeAsync

2018-07-16 2231.927 INFO 14088 --- [nio-8087-exec-5] u.d.e.e.i.VisiableThreadPoolTaskExecutor : async-service-, 2. do submit,taskCount [2], completedTaskCount [2], activeCount [0], queueSize [0]

2018-07-16 2231.929 INFO 14088 --- [async-service-3] c.u.d.e.executor.impl.AsyncServiceImpl : start executeAsync

異步線程要做的事情

可以在這里執行批量插入等耗時的事情

2018-07-16 2231.930 INFO 14088 --- [async-service-3] c.u.d.e.executor.impl.AsyncServiceImpl : end executeAsync

2018-07-16 2232.496 INFO 14088 --- [nio-8087-exec-7] u.d.e.e.i.VisiableThreadPoolTaskExecutor : async-service-, 2. do submit,taskCount [3], completedTaskCount [3], activeCount [0], queueSize [0]

2018-07-16 2232.498 INFO 14088 --- [async-service-4] c.u.d.e.executor.impl.AsyncServiceImpl : start executeAsync

異步線程要做的事情

可以在這里執行批量插入等耗時的事情

2018-07-16 2232.499 INFO 14088 --- [async-service-4] c.u.d.e.executor.impl.AsyncServiceImpl : end executeAsync

注意這一行日志:

2018-07-16 2232.496 INFO 14088 --- [nio-8087-exec-7] u.d.e.e.i.VisiableThreadPoolTaskExecutor : async-service-, 2. do submit,taskCount [3], completedTaskCount [3], activeCount [0], queueSize [0]

這說明提交任務到線程池的時候,調用的是submit(Callable task)這個方法,當前已經提交了3個任務,完成了3個,當前有0個線程在處理任務,還剩0個任務在隊列中等待,線程池的基本情況一路了然;

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • spring
    +關注

    關注

    0

    文章

    340

    瀏覽量

    14368
  • 線程池
    +關注

    關注

    0

    文章

    57

    瀏覽量

    6869
  • SpringBoot
    +關注

    關注

    0

    文章

    174

    瀏覽量

    189

原文標題:SpringBoot中的線程池,你真的會用么?

文章出處:【微信號:AndroidPush,微信公眾號:Android編程精選】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    socket 多線程編程實現方法

    在現代網絡編程,多線程技術被廣泛應用于提高服務器的并發處理能力。Socket編程是網絡通信的基礎,而將多線程技術應用于Socket編程,可以顯著提升服務器的性能。 多線程編程的基本概
    的頭像 發表于 11-12 14:16 ?437次閱讀

    怎么在JAVA確定線性大小

    在JAVA確定線性大小,分別介紹CPU密集型任務和I/O密集型任務及其處理方法。
    的頭像 發表于 10-24 14:02 ?221次閱讀

    Python線程和多進程的區別

    Python作為一種高級編程語言,提供了多種并發編程的方式,其中多線程與多進程是最常見的兩種方式之一。在本文中,我們將探討Python線程與多進程的概念、區別以及如何使用線程
    的頭像 發表于 10-23 11:48 ?455次閱讀
    Python<b class='flag-5'>中</b>多<b class='flag-5'>線程</b>和多進程的區別

    買藥秒送 JADE動態線程實踐及原理淺析

    一、背景及JADE介紹 買藥秒送是健康即時零售業務新的核心流量場域,面對京東首頁高流量曝光,我們對頻道頁整個技術架構方案進行升級,保障接口高性能、系統高可用。 動態線程是買藥頻道應用的技術之一
    的頭像 發表于 09-04 11:11 ?882次閱讀
    買藥秒送 JADE動態<b class='flag-5'>線程</b><b class='flag-5'>池</b>實踐及原理淺析

    卷積神經網絡化層的作用

    。其中,化層(Pooling Layer)作為CNN的重要組成部分,在降低模型復雜度、提高計算效率以及增強模型的不變性和魯棒性方面發揮著關鍵作用。本文將從多個方面深入探討化層的作用,力求全面解析其在CNN的核心地位。
    的頭像 發表于 07-03 15:58 ?1943次閱讀

    探索虛擬線程:原理與實現

    虛擬線程的引入與優勢 在Loom項目之前,Java虛擬機(JVM)線程是通過java.lang.Thread類型來實現的,這些線程被稱為平臺線程
    的頭像 發表于 06-24 11:35 ?340次閱讀
    探索虛擬<b class='flag-5'>線程</b>:原理與實現

    鴻蒙開發:【線程模型】

    管理其他線程的ArkTS引擎實例,例如使用TaskPool(任務)創建任務或取消任務、啟動和終止Worker線程
    的頭像 發表于 06-13 16:38 ?437次閱讀
    鴻蒙開發:【<b class='flag-5'>線程</b>模型】

    動態線程思想學習及實踐

    ://www.javadoop.com/post/java-thread-pool? 引言 在后臺項目開發過程,我們常常借助線程來實現多線程任務,以此提升系統的吞吐率和響應性;而
    的頭像 發表于 06-13 15:43 ?1224次閱讀
    動態<b class='flag-5'>線程</b><b class='flag-5'>池</b>思想學習及實踐

    OpenHarmony語言基礎類庫【@ohos.taskpool(啟動任務)】

    建的任務進行如任務執行、任務取消的操作。理論上您可以使用任務API創建數量不受限制的任務,但是出于內存因素不建議您這樣做。此外,不建議您在任務執行阻塞操作,特別是無限期阻塞操作,長時間的阻塞操作占據工作線程,可能會阻塞其他任
    的頭像 發表于 04-24 17:45 ?382次閱讀
    OpenHarmony語言基礎類庫【@ohos.taskpool(啟動任務<b class='flag-5'>池</b>)】

    鴻蒙APP開發:【ArkTS類庫多線程】TaskPool和Worker的對比

    TaskPool(任務)和Worker的作用是為應用程序提供一個多線程的運行環境,用于處理耗時的計算任務或其他密集型任務。可以有效地避免這些任務阻塞主線程,從而最大化系統的利用率,降低整體資源消耗,并提高系統的整體性能。
    的頭像 發表于 03-26 22:09 ?690次閱讀
    鴻蒙APP開發:【ArkTS類庫多<b class='flag-5'>線程</b>】TaskPool和Worker的對比

    java實現多線程的幾種方式

    了多種實現多線程的方式,本文將詳細介紹以下幾種方式: 1.繼承Thread類 2.實現Runnable接口 3.Callable和Future 4.線程 5.Java 8
    的頭像 發表于 03-14 16:55 ?767次閱讀

    python5種線程鎖盤點

    線程安全是多線程或多進程編程的一個概念,在擁有共享數據的多條線程并行執行的程序線程安全的代
    發表于 03-07 11:08 ?1650次閱讀
    python<b class='flag-5'>中</b>5種<b class='flag-5'>線程</b>鎖盤點

    基于RTOS的應用進程的典型線程

    RTOS的關鍵因素是最小的中斷延遲和最小的線程切換延遲。RTOS的價值在于它的響應速度或可預測性,而不是它在給定時間段內可以執行的工作量。
    發表于 03-05 09:32 ?685次閱讀
    基于RTOS的應用進程<b class='flag-5'>中</b>的典型<b class='flag-5'>線程</b>

    什么是動態線程?動態線程的簡單實現思路

    因此,動態可監控線程一種針對以上痛點開發的線程管理工具。主要可實現功能有:提供對 Spring 應用內線程
    的頭像 發表于 02-28 10:42 ?684次閱讀

    線程是什么的基本單位 進程與線程的本質區別

    線程是操作系統處理器調度的基本單位,它代表著獨立的執行流。在一個進程,可以包含多個線程,這些線程共享相同的進程資源,如內存空間、文件描述
    的頭像 發表于 02-02 16:30 ?988次閱讀
    主站蜘蛛池模板: 717影院理论午夜伦不卡久久| 手机在线观看mv网址| 成人小视频免费在线观看| 一个人免费完整在线观看影院 | 美女诱惑性感揉胸| 蜜臀久久99精品久久久久久做爰| 日本无码免费久久久精品| 色内射无码AV| 亚洲成人一区二区| 一本道久久综合久久88| 18亚洲男同gay1069| 91嫩草视频在线观看| china男士同性视频tv| 岛国片在线免费观看| 国产日韩在线欧美视频| 精品高潮呻吟99AV无码| 久久亚洲精品永久网站| 嫩草欧美曰韩国产大片| 涩涩爱涩涩电影网站| 亚洲AV 中文字幕 国产 欧美| 亚洲久热无码中文字幕| 自慰弄湿白丝袜| JAPANRCEP老熟妇乱子伦视频| 精品久久日日躁夜夜躁AV| 男人插曲女人的视频| 亚洲乱码爆乳精品成人毛片| 多男同时插一个女人8p| 韩日美无码精品无码| 美女与男人对肌免费网站| 亚洲乱码一区二区三区香蕉| 国产99久久久欧美黑人刘玥| 久久黄视频| 乳巨揉みま痴汉电车中文字幕动漫| 在线日本高清日本免费| 草莓国产视频免费观看| 好大好硬好爽好深好硬视频| 十大禁止安装的黄台有风险| 芭乐草莓樱桃丝瓜18岁大全| 鸡鸡插屁股| 亚洲精品欧美精品中文字幕| 国产精品久久高潮呻吟无码|