执行程序工厂方法 newScheduledThreadPool 始终返回相同的线程池



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

但根据我的经验,即使我创建两个单独的ScheduledExecutorService调用 newScheduledThreadPool(int corePoolSize) Factory 方法两次并调度两个完全不同的 Callable 任务,两个线程也会同步运行,即一个等待另一个。考虑到已经创建了两个单独的线程池,它们应该同时运行。

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

你的代码和你对工作原理的理解有很多问题。

首先 - 如评论中所述 - 您在两个池中使用相同的扫描程序实例。这就解释了为什么你只能从"一个"线程获得输出。

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

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)

对线程的概念存在误解。如果您有 2 个池(每个池有 10 个线程)或 1 个池(每个池有 20 个线程)都没有关系。在您的示例中,如果您只有 1 个池和 1 个线程,它甚至不会有什么区别。使用多个池的唯一原因是以不同的方式管理这些池,而不是让其中的线程"单独"运行。 因此,要回答您的实际问题,Java 如何在内部管理这些池并不重要。

我不知道您的其余代码,

但是您检查池是否已关闭然后创建一个新池的事实告诉我,您的代码整体存在体系结构问题。仅当所有工作都已完成并且主线程需要等待所有线程完成以处理数据或退出时,才需要关闭池。使用线程池来节省线程创建的开销成本,然后一遍又一遍地创建池,这是特别没有意义的。

关于您要存档的内容的信息太少,无法提供任何进一步的建议,但我很确定无论您要做什么,都可以比您呈现的方式简单得多。如果您重新发布以获取架构帮助,可能会有所帮助。

这是这个场景:

public class ThreadA implements Runnable{
@Override
public void run() {
    // TODO Auto-generated method stub
    Date startTime =new Date();
    System.out.println("Thread A started at - "+startTime);
    try {
        Thread.sleep(4000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    Date endTime =new Date();
    System.out.println("Thread A ended at - "+endTime);
    System.out.println("Time taken by Thread A - "+(endTime.getTime()-startTime.getTime())+"ms");
}}
public class ThreadB implements Runnable {
@Override
public void run() {
    // TODO Auto-generated method stub
    Date startTime = new Date();
    System.out.println("Thread B started at - " + startTime);
    try {
        Thread.sleep(60000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    Date endTime = new Date();
    System.out.println("Thread B ended at - " + endTime);
    System.out.println("Time taken by Thread B - "+ (endTime.getTime() - startTime.getTime()) + "ms");
}}
public class ExecutorTest {
public static ScheduledExecutorService EXECUTOR_A = Executors.newScheduledThreadPool(10);
public static ScheduledExecutorService EXECUTOR_B = Executors.newScheduledThreadPool(10);
public static void main(String[] args) {
    ThreadA threadA=new ThreadA();
    ThreadB threadB=new ThreadB();
    if(EXECUTOR_A.isShutdown())
        EXECUTOR_A=Executors.newScheduledThreadPool(10);
    EXECUTOR_A.scheduleWithFixedDelay(threadA, 0, 30, TimeUnit.SECONDS);
    if(EXECUTOR_B.isShutdown())
        EXECUTOR_B=Executors.newScheduledThreadPool(10);
    EXECUTOR_B.scheduleWithFixedDelay(threadB, 0, 40, TimeUnit.SECONDS);
}}

输出:

主题 A 开始于 - 周四 11 月 07 日 12:22:12 IST 2013
主题 B 开始于 - 周四 11月 07 12:22:12 IST 2013
主题 A 结束于 - 周四 11月 07 12:22:16 IST 2013
线程 A 花费的时间 - 4025ms
主题 A 开始于 - 周四 11月 07 12:22:46 IST 2013
主题 A 结束于 - 周四 11月 07 12:22:50 IST 2013
线程 A 花费的时间 - 4010ms
主题 B 结束于 - 周四 11 月 07 日 12:23:12 IST 2013
线程 B 花费的时间 - 59996ms
主题 A 开始于 - 周四 11 月 07 日 12:23:20 IST 2013
主题 A 结束于 - 周四 11月 07 12:23:24 IST 2013
线程 A 花费的时间 - 4010ms

完美的输出设计。这是我的场景,但在这里完美地工作。将再次重新检查我的代码。

相关内容

  • 没有找到相关文章

最新更新