本文介绍了执行器工厂方法newScheduledThreadPool始终返回相同的线程池的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据Java规范:public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)创建一个线程池,该线程池可以安排命令在给定的延迟后运行或定期执行."

As per the Java Specifications:public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)"Creates a thread pool that can schedule commands to run after a given delay, or to execute periodically."

但是根据我的经验,即使我创建了两个分别调用newScheduledThreadPool(int corePoolSize)工厂方法的单独的ScheduledExecutorService并计划了两个完全不同的Callable任务,两个线程也同步运行,即一个线程在等待另一个线程.考虑到已经创建了两个单独的线程池,它们应该同时运行.

But from my experience even if I create two seperate ScheduledExecutorService calling the newScheduledThreadPool(int corePoolSize) factory method twice and schedule two completely different Callable tasks, both the threads run synchonously i.e. one waits on the other. Considering two seperate thread pools have been created, they shoud have run simultaneously.

public static ScheduledExecutorService SCANNER_SERVICE = Executors.newScheduledThreadPool(10);
public static ScheduledExecutorService UNSERVICERESTORED_SCANNER_SERVICE = Executors.newScheduledThreadPool(10);

Scanner scanner=new Scanner();
UnServiceRestoredTicketScanner unServiceRestoredTicketScanner=new UnServiceRestoredTicketScanner();

if(SCANNER_SERVICE.isShutdown())
    SCANNER_SERVICE=Executors.newScheduledThreadPool(10);
SCANNER_SERVICE.scheduleWithFixedDelay(scanner, 0, 30, TimeUnit.SECONDS);


if(UNSERVICERESTORED_SCANNER_SERVICE.isShutdown())
    UNSERVICERESTORED_SCANNER_SERVICE=Executors.newScheduledThreadPool(10);
UNSERVICERESTORED_SCANNER_SERVICE.scheduleWithFixedDelay(unServiceRestoredTicketScanner, 0, 40, TimeUnit.SECONDS);

输出:

Scanner Thread started - com.csp.productionsupport.queuemonitor.events.Scanner@1fa6d18
ServiceRestoredTicketScanner Thread started - com.csp.productionsupport.queuemonitor.events.UnServiceRestoredTicketScanner@15ed659
Thread ended - com.csp.productionsupport.queuemonitor.events.Scanner@1fa6d18
Scanner Thread started - com.csp.productionsupport.queuemonitor.events.Scanner@1fa6d18
ServiceRestoredTicketScanner Thread ended - com.csp.productionsupport.queuemonitor.events.UnServiceRestoredTicketScanner@15ed659
Thread ended - com.csp.productionsupport.queuemonitor.events.Scanner@1fa6d18
Scanner Thread started - com.csp.productionsupport.queuemonitor.events.Scanner@1fa6d18
ServiceRestoredTicketScanner Thread started - com.csp.productionsupport.queuemonitor.events.UnServiceRestoredTicketScanner@15ed659
Thread ended - com.csp.productionsupport.queuemonitor.events.Scanner@1fa6d18
Scanner Thread started - com.csp.productionsupport.queuemonitor.events.Scanner@1fa6d18
ServiceRestoredTicketScanner Thread ended - com.csp.productionsupport.queuemonitor.events.UnServiceRestoredTicketScanner@15ed659
Thread ended - com.csp.productionsupport.queuemonitor.events.Scanner@1fa6d18

推荐答案

您的代码有很多问题,您对事情的工作方式也有所了解.

There are a lot of things wrong with your code and your understanding of how things work.

首先-正如注释中已经提到的-您在两个池中使用相同的扫描仪实例.这解释了为什么只从一个"线程获得输出.

First - as mentioned already in the comment - you are using the same scanner instance in both pools. This explains why you only get output from "one" thread.

由于您将这些线程安排为每30/40秒进行一次,因此它们不会在前3-4个运行中并行运行:

Since you schedule these threads for each 30/40 seconds, they will not run in parallel for the first 3-4 runs each:

30s: Thread A
40s: Thread B
60s: Thread A
80s: Thread B
90s: Thread A
120s: Thread A + B (it will be "random" which one runs first)

对线程概念有误解.拥有两个具有10个线程的池,还是拥有20个线程的1个池,都没关系.在您的示例中,如果只有1个线程池和1个线程,那甚至都不会起作用.使用多个池的唯一原因是对那些池进行不同的管理,并且不要让线程内部单独"运行.因此,要回答您的实际问题,Java在内部如何管理这些池都没关系.

There is a misunderstanding of the concept Thread. It doesn't matter if you have 2 pools with 10 threads each, or 1 pool with 20 threads. In your example it wouldn't even make a difference if you have only 1 pool with 1 threads. The only reason to use more than one pool is to manage those pools differently and not to have threads inside run "separately". Therefore, to answer your actual question, it doesn't matter how Java manages those pools internally.

我不知道您代码的其余部分,但是您检查一个池是否已关闭然后创建一个新池的事实告诉我,您的代码总体上存在体系结构问题.仅当完成所有工作并且主线程需要等待所有线程完成以处理数据或退出时,才需要关闭池.使用线程池来节省线程创建的开销成本,然后一遍又一遍地创建该池,这毫无意义.

I don't know the rest of your code, but the fact that you check if a pool is shut down and then create a new one, tells me that there is an architectural issue in your code at a whole. Shutting down a pool is only necessary if all work is done and the main thread needs to wait for all threads to finish to either process the data or exit. It is especially pointless to use a thread pool to save the overhead cost of thread creation and then create the pool over and over again.

关于您要归档的内容的信息太少,无法给出任何进一步的建议,但是我很确定,无论您想做什么,都可以比您介绍的方法简单得多.如果您重新发布以寻求体系结构帮助,则可能会有所帮助.

There is too little information on what you are trying to archive to give any further suggestions, but I am pretty sure that whatever you are trying to do, it is possible to do this a lot simpler than the way you presented. It might be helpful if you repost for an architectural help instead.

这篇关于执行器工厂方法newScheduledThreadPool始终返回相同的线程池的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-01 00:16