并行查询的超时时间设置

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

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();
    }
}
相关推荐
ForgeAI码匠18 小时前
后台权限不只是菜单隐藏:Forge Admin 的 RBAC 权限链路拆解
java·spring boot·spring·状态模式
赴前尘18 小时前
Go 语言实现 TOTP 双因素认证完整指南
开发语言·后端·golang
yugi98783818 小时前
基于Qt的图像处理系统
开发语言·图像处理·qt
码界筑梦坊18 小时前
150-基于Python的中国海洋水质数据可视化分析系统
开发语言·python·信息可视化·django·毕业设计
chushiyunen18 小时前
golang笔记、go
开发语言·笔记·golang
一条泥憨鱼18 小时前
详解MyBatis 动态 SQL
java·数据库·sql·mysql·mybatis·动态sql
青枣八神18 小时前
Trae IDE 终端 JDK 版本与系统不一致的解决方案
java·开发语言·ide
Shadow(⊙o⊙)18 小时前
Linux内核级文件系统分析——文件系统入门内核级文章!
linux·运维·服务器·开发语言·c++
cjhbachelor18 小时前
C/C++内存管理
c语言·开发语言·c++
噜噜大王_18 小时前
C++ 类和对象(中):默认成员函数全解
开发语言·c++