多线程实现的方式
java.util.concurrent 包下面的类 Executor
java.util.concurrent 包下面的类 ExecutorService pool = Executors.newCachedThreadPool(); 有4个静态方法可以创建不同的类型的线程池
springboot 项目里面可以利用框架封装的线程池和注解实现异步 这个是我们这次讲解的重点
首先配置类
@Component
@Configuration
public class TaskExecutorConfig implements AsyncConfigurer{
@Override
@Bean
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(20);// 设置核心的线程数量
taskExecutor.setMaxPoolSize(50);// 设置最大的线程数量
taskExecutor.setKeepAliveSeconds(8);//空闲时间s
taskExecutor.setAwaitTerminationSeconds(3);//等待阻塞最长时间s
taskExecutor.initialize();// 初始化
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new ExceptionHandlingAsyncTaskExecutor();
}
}
定义子线异常的处理方法 多线程执行的时候子线程的异常不会每次都能够打印出来 需要配置这个类来打印子线程的异常
@Component
@Configuration
public class ExceptionHandlingAsyncTaskExecutor implements AsyncUncaughtExceptionHandler{
private static final Logger logger = LoggerFactory.getLogger(ExceptionHandlingAsyncTaskExecutor.class);
@Override
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
logger.info("Method name - " + method.getName());
logger.info("Exception message - " + ex.getMessage());
for (Object param : params) {
logger.info("Parameter value - " + param);
}
}
}
启动类上面增加配置
@EnableAsync
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
让方法异步执行只有一个注解就可以 @Async 主线程只想到这个方法的时候回就回创建一个新的线程
@Async
@Override
public List getMbiIndex(CountDownLatch downLatch) {
downLatch.countDown();
}
情景:给前段返回多个数据 请求多个service里面的多个方法 每个方法都是异步的,主线程等待异步的线程执行完毕之后统一返回给前段
这里需要用到一个对象 CountDownLatch
// 构造方法 cout需要计数的线程的个数
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
// 等待所有计算都清零再继续执行
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
// 等待所有记录都清零再执行 规定时间内没有清零就不再等待
public boolean await(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
//线程清理计数的功能 每个子线程完成任务执行这方法就可以清楚该线程的计数
public void countDown() {
sync.releaseShared(1);
}
主方法
public Object mian(){
CountDownLatch downLatch= new CountDownLatch(3);
Future<List> list1=test1(downLatch)
Future<List> list2=test2(downLatch)
Future<List> list3=test3(downLatch)
downLatch.await(4L, TimeUnit.SECONDS);
return list1.get();
}
Future<List> test1(CountDownLatch downLatch){
………
downLatch.countDown();
return
new AsyncResult<List>(new ArrayList());
}
test2() 和 test3()也是要调用这个downLatch.countDown();
版权声明:本文为sswltt原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。