ThreadPoolExecutor:JDK內建執行緒池實現
ThreadPoolTaskExecutor:Spring對JDK中執行緒池做了一層封裝
參考程式碼:https://github.com/Noneplus/ConcurrentDemo
建立一個SpringBoot專案
主類開啟非同步註解
/**
* 開啟非同步註解@EnableAsync
*/
@SpringBootApplication
@EnableAsync
public class AsyncApplication {
public static void main(String[] args) {
SpringApplication.run(AsyncApplication.class, args);
}
}
建立執行緒池配置類
主類新增註解:@EnableConfigurationProperties({AsyncThreadPoolConfig.class} )
/**
* @Description: 執行緒池引數配置
* @Author noneplus
* @Date 2020/8/5 19:02
*/
@ConfigurationProperties("task.pool")
public class AsyncThreadPoolConfig{
private Integer corePoolSize;
private Integer maxPoolSize;
private Integer keepAliveSeconds;
private Integer queueCapacity;
public Integer getCorePoolSize() {
return corePoolSize;
}
public void setCorePoolSize(Integer corePoolSize) {
this.corePoolSize = corePoolSize;
}
public Integer getMaxPoolSize() {
return maxPoolSize;
}
public void setMaxPoolSize(Integer maxPoolSize) {
this.maxPoolSize = maxPoolSize;
}
public Integer getKeepAliveSeconds() {
return keepAliveSeconds;
}
public void setKeepAliveSeconds(Integer keepAliveSeconds) {
this.keepAliveSeconds = keepAliveSeconds;
}
public Integer getQueueCapacity() {
return queueCapacity;
}
public void setQueueCapacity(Integer queueCapacity) {
this.queueCapacity = queueCapacity;
}
}
建立執行緒池實現類
繼承AsyncConfigurer,重寫get方法
package com.noneplus.async;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @Description: 重寫Spring執行緒池
* @Author noneplus
* @Date 2020/8/6 10:11
*/
public class AsyncThreadPool implements AsyncConfigurer {
@Autowired
AsyncThreadPoolConfig asyncThreadPoolConfig;
/**
* ThreadPoolTaskExecutor 對比 ThreadPoolExecutor
* ThreadPoolExecutor:JDK內建執行緒池
* ThreadPoolTaskExecutor:Spring對ThreadPoolExecutor做了一層基礎封裝
*
* 相比 ThreadPoolExecutor,ThreadPoolTaskExecutor 增加了 submitListenable 方法,
* 該方法返回 ListenableFuture 介面物件,該介面完全抄襲了 google 的 guava。
* ListenableFuture 介面物件,增加了執行緒執行完畢後成功和失敗的回撥方法。
* 從而避免了 Future 需要以阻塞的方式呼叫 get,然後再執行成功和失敗的方法。
*/
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
//設定核心執行緒數,最大執行緒數,佇列容量,執行緒存活時間
threadPoolTaskExecutor.setCorePoolSize(asyncThreadPoolConfig.getCorePoolSize());
threadPoolTaskExecutor.setMaxPoolSize(asyncThreadPoolConfig.getMaxPoolSize());
threadPoolTaskExecutor.setQueueCapacity(asyncThreadPoolConfig.getQueueCapacity());
threadPoolTaskExecutor.setKeepAliveSeconds(asyncThreadPoolConfig.getKeepAliveSeconds());
//設定執行緒名字首
threadPoolTaskExecutor.setThreadNamePrefix("AsyncThreadPool-");
// setRejectedExecutionHandler:當pool已經達到max size的時候,如何處理新任務
// CallerRunsPolicy:不在新執行緒中執行任務,而是由呼叫者所在的執行緒來執行
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 等待所有任務結束後再關閉執行緒池
threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
}
建立一個測試類Controller
定義一個forTest方法
/**
* @Description: TODO(這裡用一句話描述這個類的作用)
* @Author noneplus
* @Date 2020/8/5 18:33
*/
@RestController
public class TestController {
@Autowired
TestService testService;
@GetMapping("/test")
public String forTest()
{
testService.forTest();
return "success";
}
}
建立非同步Service方法
共三個執行緒,sendEmail,recoredLog和主執行緒
@Service
public class TestService {
@Autowired
TaskComponent taskComponent;
public void forTest() {
taskComponent.sendEmail();
taskComponent.recordLog();
for (int i = 0; i < 10; i++) {
System.out.println("打醬油:" + i+"當前執行緒:"+Thread.currentThread().getName());
}
}
}
定義非同步的實現類
@Component
public class TaskComponent {
@Async
public void sendEmail()
{
for (int i = 0; i < 10; i++) {
System.out.println("傳送簡訊中:" + i+"當前執行緒:"+Thread.currentThread().getName());
}
}
@Async
public void recordLog()
{
for (int i = 0; i < 10; i++) {
System.out.println("記錄日誌中:" + i+"當前執行緒:"+ Thread.currentThread().getName());
}
}
}