1

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

但是根据我的经验,即使我创建了两个单独ScheduledExecutorService调用newScheduledThreadPool(int corePoolSize)工厂方法两次并安排两个完全不同的 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
4

2 回答 2

4

您的代码和您对工作原理的理解存在很多问题。

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

由于您为每 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 如何在内部管理这些池并不重要。

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

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

于 2013-11-06T15:39:37.567 回答
0

这是这个场景:

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 开始于 - Thu Nov 07 12:22:12 IST 2013
线程 B 开始于 - Thu Nov 07 12:22:12 IST 2013
线程 A 结束于 - Thu Nov 07 12:22:16 IST 2013
线程 A 花费的时间- 4025ms
线程 A 开始于 - 2013 年 11 月 7 日星期四 12:22:46 IST 2013
线程 A 结束于 - 2013 年 11 月 7 日星期四 12:22:50 IST 2013 线程 A
花费的时间 - 4010ms
线程 B 结束于 - 11 月 7 日星期四 12:23 :12 IST 2013
线程 B 花费的时间 - 59996 毫秒
线程 A 开始于 - 11 月 7 日星期四 12:23:20 IST 2013
线程 A 结束于 - 11 月 7 日星期四12:23:24 IST 2013 线程 A
花费的时间 - 4010 毫秒

按设计完美输出。这是我的场景,但在这里完美运行。将再次检查我的代码。

于 2013-11-07T06:58:28.133 回答