Spring Boot +多线程+处理连接池

时间:2019-01-01 07:22:10

标签: java multithreading spring-boot

我有一个Spring-boot应用程序,其中包含以下内容:
1. REST-API
2.从开始运行的一个线程将执行一项服务BS(我们可以说后台服务)

注意BS具有创建 10 子线程的代码,该子线程异步运行以完成任务。

要求
1. BS是独立线程,将使用主线程在整个应用程序中运行。
2. Child thread:将在BS中创建,完成后将在BS中折叠。

问题:如果没有待处理的工作,我的线程BS需要休眠(或者您可以说处于wait状态)并返回(notify)随着工作的到来。为此,我使用了传统的方法wait...notify,但是在等待BS线程时, 10 子线程正在执行与BS线程相同的代码。我认为线程池管理没有正确处理。
帮助欣赏

BS Thread ThreadPoolTask​​Executor CommandLineRunner 且连接池设置为1

 ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();  
    executor.setCorePoolSize(1);  
    executor.setMaxPoolSize(1);  
    executor.setQueueCapacity(500);  
    executor.setThreadNamePrefix("BS Thread:");  
    executor.initialize();  
    return executor;   

Child Thread:使用以下代码创建的 10 个线程:

 ExecutorService service = Executors.newFixedThreadPool(10);
 for (BSChildExecutor jobs : listOfJobs) {
     service.submit(jobs);
 }  
 service.shutdown();`    

1 个答案:

答案 0 :(得分:1)

我认为您的设计存在缺陷。您想要实现的流程可以大大简化。

首先,您添加了BS,这是完全不需要的。典型的BS是包括日志记录,系统监视,调度,通知等的过程。

对于您来说,BS是线程池固有提供的。

创建一个满足您要求的X大小的线程池,直到您正常关闭Spring应用程序,该线程池才会消失。 由于REST API是执行listOfJobs的触发点,因此,每当有新作业出现时,您就继续提交到池中。

该代码段用于在正常关闭Spring Application的同时优雅地关闭线程池

public void onApplicationEvent(ContextClosedEvent event) {
        this.connector.pause();
        Executor executor = this.connector.getProtocolHandler().getExecutor();
        if (executor instanceof ThreadPoolExecutor) {
            try {
                ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
                threadPoolExecutor.shutdown();
                if (!threadPoolExecutor.awaitTermination(TIMEOUT, TimeUnit.SECONDS)) {
                    log.warn("Thread pool did not shut down gracefully within "
                            + TIMEOUT + " seconds. Proceeding with forceful shutdown");

                    threadPoolExecutor.shutdownNow();

                    if (!threadPoolExecutor.awaitTermination(TIMEOUT, TimeUnit.SECONDS)) {
                        log.error("Thread pool did not terminate");
                    }
                }
            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
        }
    }