SPRING ThreadPoolTaskExecutor示例
0、前言
当我们需要实现并发、异步等操作时,通常都会使用到ThreadPoolTaskExecutor。它是springcore包中的,而ThreadPoolExecutor是JDK中的JUC。ThreadPoolTaskExecutor是对ThreadPoolExecutor进行了封装处理。
1、示例一
1.1、配置类
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;
@EnableAsync
@Configuration
public class ExecutorConfig {
@Bean(name = "asyncServiceExecutor")
public Executor asyncServiceExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//设置核心线程数
executor.setCorePoolSize(10);
//设置最大线程数
executor.setMaxPoolSize(30);
//设置队列大小
executor.setQueueCapacity(50);
//配置线程池的前缀
executor.setThreadNamePrefix("async-service-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//设置空闲时间
executor.setKeepAliveSeconds(60);
//进行加载
executor.initialize();
return executor;
}
}
1.2、应用
1.2.0 需异步的方法
import com.baomidou.mybatisplus.extension.service.IService;
import com.chengd.pojo.GeneCase;
public interface GeneCaseService extends IService<GeneCase>
{
void testThread() throws InterruptedException;
}
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chengd.mapper.GeneCaseMapper;
import com.chengd.pojo.GeneCase;
import com.chengd.service.GeneCaseService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class GeneCaseServiceImpl extends ServiceImpl<GeneCaseMapper, GeneCase> implements GeneCaseService {
@Override
@Async
public void testThread() throws InterruptedException {
for (int i = 0; i < 200; i++) {
System.out.println("副线程名称 " + Thread.currentThread().getName() + " === " + i);
Thread.sleep(5);
}
}
}
1.2.1 Controller
import com.chengd.common.Result;
import com.chengd.service.TestService;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@RequestMapping("/test")
@Api(tags = "测试ThreadPoolTaskExecutor")
public class TestController {
@Resource
private TestService testService;
@GetMapping("/thread")
public Result<Object> testThread() throws InterruptedException {
testService.testThread();
return Result.succeed("请求成功");
}
}
1.2.2 Service
public interface TestService {
/**
* 测试Thread
*/
void testThread() throws InterruptedException;
}
import com.chengd.service.GeneCaseService;
import com.chengd.service.TestService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class TestServiceImpl implements TestService {
@Resource
private GeneCaseService geneCaseService;
@Resource(name = "asyncServiceExecutor")
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Override
public void testThread() throws InterruptedException {
threadPoolTaskExecutor.submit(()-> {
try {
test();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
threadPoolTaskExecutor.submit(() -> {
try {
geneCaseService.testThread();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
for (int i = 0; i < 200; i++) {
System.out.println("主线程名称 " + Thread.currentThread().getName() + " === " + i);
Thread.sleep(5);
}
}
@Async
void test() throws InterruptedException {
for (int i = 0; i < 200; i++) {
System.out.println("jei线程名称 " + Thread.currentThread().getName() + " === " + i);
Thread.sleep(5);
}
}
}
1.3、测试结果
注意事项:
配置类的 @EnableAsync
需异步方法的 @Async
2、示例二
2.1、配置类
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@Slf4j
@Configuration
public class AsyncTaskExecutePool implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//核心线程池大小
executor.setCorePoolSize(AsyncTaskProperties.corePoolSize);
//最大线程数
executor.setMaxPoolSize(AsyncTaskProperties.maxPoolSize);
//队列容量
executor.setQueueCapacity(AsyncTaskProperties.queueCapacity);
//活跃时间
executor.setKeepAliveSeconds(AsyncTaskProperties.keepAliveSeconds);
//线程名字前缀
executor.setThreadNamePrefix("el-async-");
// setRejectedExecutionHandler:当pool已经达到max size的时候,如何处理新任务
// CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return (throwable, method, objects) -> {
log.error("====" + throwable.getMessage() + "====", throwable);
log.error("exception method:" + method.getName());
};
}
}
2.2、应用
①项目结构与示例一相同
②与示例一实现类不同:
import com.chengd.service.GeneCaseService;
import com.chengd.service.TestService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class TestServiceImpl implements TestService {
@Resource
private GeneCaseService geneCaseService;
// @Resource(name = "asyncServiceExecutor")
// private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Resource
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Override
public void testThread() throws InterruptedException {
threadPoolTaskExecutor.submit(()-> {
try {
test();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
threadPoolTaskExecutor.submit(() -> {
try {
geneCaseService.testThread();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
for (int i = 0; i < 200; i++) {
System.out.println("主线程名称 " + Thread.currentThread().getName() + " === " + i);
Thread.sleep(5);
}
}
@Async
void test() throws InterruptedException {
for (int i = 0; i < 200; i++) {
System.out.println("jei线程名称 " + Thread.currentThread().getName() + " === " + i);
Thread.sleep(5);
}
}
}
2.3、测试结果
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· 地球OL攻略 —— 某应届生求职总结