Springboot實現(xiàn)多線程及線程池監(jiān)控
線程池的優(yōu)點
- 降低資源消耗。通過重復(fù)利用已創(chuàng)建的線程降低線程創(chuàng)建和銷毀造成的消耗
- 提高響應(yīng)速度。當任務(wù)到達時,任務(wù)可以不需要等到線程創(chuàng)建就能立即執(zhí)行
- 可以對線程做統(tǒng)一管理。
1.配置線程池
修改配置文件
# 異步線程配置
# 配置核心線程數(shù)
async:
executor:
thread:
core_pool_size: 5 # 配置核心線程數(shù)
max_pool_size: 5 # 配置最大線程數(shù)
queue_capacity: 99999 # 配置隊列大小
name:
prefix: async-service- # 配置線程池中的線程的名稱前
線程池配置類
package com.bt.springboot.config;
import com.bt.springboot.task.ThreadPoolMonitor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @author zkx
* @Date 2022/12/6 21:42
*/
@Slf4j
@Configuration
@EnableAsync
public class ExecutorConfig {
@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() {
log.info("start asyncServiceExecutor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//配置核心線程數(shù)
executor.setCorePoolSize(corePoolSize);
//配置最大線程數(shù)
executor.setMaxPoolSize(maxPoolSize);
//配置隊列大小
executor.setQueueCapacity(queueCapacity);
//配置線程池中的線程的名稱前綴
executor.setThreadNamePrefix(namePrefix);
// rejection-policy:當pool已經(jīng)達到max size的時候,如何處理新任務(wù)
// CALLER_RUNS:不在新線程中執(zhí)行任務(wù),而是有調(diào)用者所在的線程來執(zhí)行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//執(zhí)行初始化
executor.initialize();
return executor;
}
}
2.監(jiān)控類
package com.bt.springboot.task;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @Author: ChenBin
*/
@Slf4j
@Component
public class ThreadPoolMonitor extends ThreadPoolTaskExecutor {
@Value("${async.executor.thread.name.prefix}")
private String namePrefix;
@Scheduled(cron = "0/1 * * * * ? ")
private void showThreadPoolInfo() {
ThreadPoolExecutor threadPoolExecutor = getThreadPoolExecutor();
if (namePrefix.equals(this.getThreadNamePrefix())){
log.info("{} taskCount [{}], completedTaskCount [{}], activeCount [{}], queueSize [{}]",
this.getThreadNamePrefix(),
threadPoolExecutor.getTaskCount(),
threadPoolExecutor.getCompletedTaskCount(),
threadPoolExecutor.getActiveCount(),
threadPoolExecutor.getQueue().size());
}
}
}
開啟定時任務(wù)

3.修改線程池配置類
將ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
修改為ThreadPoolTaskExecutor executor = new ThreadPoolMonitor();
4.測試相關(guān)類
AsyncService
package com.bt.springboot.async;
/**
* @author zkx
* @Date 2022/12/6 21:47
*/
public interface AsyncService {
/**
* 執(zhí)行異步任務(wù)
* 可以根據(jù)需求,自己加參數(shù)擬定,我這里就做個測試演示
*/
void executeAsync();
}
AsyncServiceImpl
package com.bt.springboot.async.impl;
import com.bt.springboot.async.AsyncService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
/**
* @author zkx
* @Date 2022/12/6 21:48
*/
@Slf4j
@Service
public class AsyncServiceImpl implements AsyncService {
@Override
@Async("asyncServiceExecutor")
public void executeAsync() {
int i = 5;
while(i > 0){
i--;
log.info("execute task");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
}
AsyncController
package com.bt.springboot.web.controller;
import com.bt.springboot.async.AsyncService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author zkx
* @Date 2022/12/9 17:38
*/
@RestController
public class AsyncController {
@Autowired
private AsyncService asyncService;
@GetMapping("/asyncTask")
public void asyncTask(){
asyncService.executeAsync();
}
}
5.啟動
1.執(zhí)行任務(wù)前

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

3.任務(wù)完成

到此這篇關(guān)于Springboot實現(xiàn)多線程及線程池監(jiān)控的文章就介紹到這了,更多相關(guān)Springboot 多線程及線程池監(jiān)控內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于Mybatis和JDBC的使用及區(qū)別
這篇文章主要介紹了關(guān)于Mybatis和JDBC的使用及區(qū)別,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-05-05
Java中的System.arraycopy()淺復(fù)制方法詳解
這篇文章主要介紹了Java中的System.arraycopy()淺復(fù)制方法詳解,Java數(shù)組的復(fù)制操作可以分為深度復(fù)制和淺度復(fù)制,簡單來說深度復(fù)制,可以將對象的值和對象的內(nèi)容復(fù)制;淺復(fù)制是指對對象引用的復(fù)制,需要的朋友可以參考下2023-11-11
SpringAop @Aspect織入不生效,不執(zhí)行前置增強織入@Before方式
這篇文章主要介紹了SpringAop @Aspect織入不生效,不執(zhí)行前置增強織入@Before方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
Spring MVC url提交參數(shù)和獲取參數(shù)
本文重要講述通過url提交參數(shù)和獲取參數(shù)的具體操作與實現(xiàn)。具有很好的參考價值。下面跟著小編一起來看下吧2017-04-04
Spring中@Autowired @Resource @Inject三個注解有什么區(qū)別
在我們使用Spring框架進行日常開發(fā)過程中,經(jīng)常會使用@Autowired, @Resource, @Inject注解來進行依賴注入,下面來介紹一下這三個注解有什么區(qū)別2023-03-03

