众所周知,并行查询可以提高程序运行效率。主线程需要等待所有子线程把数据查询出结果,如果没有设置超时时间,就需要主线程就会一直阻塞到那里,从而占用服务器资源,那么如何设置超时时间呢?
1.在SpringBoot项目中引入线程池
java
@EnableAsync
@Configuration
public class ThreadPoolsConfig {
@Value("${AsyncTaskExecutor.corePooleSize:6}")
private Integer corePooleSize;
@Value("${AsyncTaskExecutor.maxPoolSize:15}")
private Integer maxPoolSize;
@Value("${AsyncTaskExecutor.queueCapacity:20000}")
private Integer queueCapacity;
/**
* 自定义线程池
*/
@Bean("myTaskExecutor")
public AsyncTaskExecutor getMyTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix("TaskThreadExec--");
executor.setCorePoolSize(corePooleSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
// 放弃等待队列中最旧的任务来添加新的任务
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
return executor;
}
}
2.使用java.util.concurrent.CompletableFuture进行并行查询(未设置超时时间)
java
CompletableFuture[] asyncList = new CompletableFuture[]{
CompletableFuture.runAsync(() -> queryDataA(), asyncTaskExecutor),
CompletableFuture.runAsync(() -> queryDataB(), asyncTaskExecutor)
};
CompletableFuture.allOf(asyncList).join();
3.使用java.util.concurrent.CompletableFuture进行并行查询(设置超时时间)
java
CompletableFuture[] asyncList = new CompletableFuture[]{
CompletableFuture.runAsync(() -> queryDataA(), asyncTaskExecutor),
CompletableFuture.runAsync(() -> queryDataB(), asyncTaskExecutor)
};
try {
CompletableFuture.allOf(asyncList).get(3, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
System.err.println("多线程查询"+e.getMessage());
Thread.currentThread().interrupt();
}
需要说明的是,这里的interrupt方法也可以不调用。
interrupt方法的作用如下:
线程A在执行sleep,wait,join时,线程B调用线程A的interrupt方法,的确这一个时候A会有InterruptedException 异常抛出来。
但这其实是在sleep、wait、join这些方法内部会不断检查中断状态的值,而自己抛出的InterruptedException
java
import java.util.Date;
public class MyThread extends Thread{
@Override
public void run() {
while (!isInterrupted()){
System.out.println(new Date());
}
}
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
myThread.start();
//1秒后打断子线程
Thread.sleep(1000);
myThread.interrupt();
}
}