我有一个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
: ThreadPoolTaskExecutor 和 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();`
答案 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();
}
}
}