并行查询的超时时间设置

众所周知,并行查询可以提高程序运行效率。主线程需要等待所有子线程把数据查询出结果,如果没有设置超时时间,就需要主线程就会一直阻塞到那里,从而占用服务器资源,那么如何设置超时时间呢?

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();
    }
}
相关推荐
颜淡慕潇几秒前
Redis 实现分布式锁:深入剖析与最佳实践(含Java实现)
java·redis·分布式
程序员秘密基地7 分钟前
基于vscode,idea,java,html,css,vue,echart,maven,springboot,mysql数据库,在线考试系统
java·vue.js·spring boot·spring·web app
何中应8 分钟前
【设计模式-5】设计模式的总结
java·后端·设计模式
草莓熊Lotso9 分钟前
【数据结构初阶】--算法复杂度的深度解析
c语言·开发语言·数据结构·经验分享·笔记·其他·算法
海的诗篇_25 分钟前
前端开发面试题总结-JavaScript篇(二)
开发语言·前端·javascript·typescript
吾日三省吾码26 分钟前
Spring 团队详解:AOT 缓存实践、JSpecify 空指针安全与支持策略升级
java·spring·缓存
风象南44 分钟前
SpringBoot的5种日志输出规范策略
java·spring boot·后端
cccc来财1 小时前
Go中的协程并发和并发panic处理
开发语言·后端·golang
咖啡啡不加糖1 小时前
深入理解MySQL死锁:从原理、案例到解决方案
java·数据库·mysql
zimoyin1 小时前
Compose Multiplatform 实现自定义的系统托盘,解决托盘乱码问题
java