繁体   English   中英

ScheduledExecutorService并行多个线程

[英]ScheduledExecutorService multiple threads in parallel

如果之前的任务尚未完成,我有兴趣使用ScheduledExecutorService为任务生成多个线程。 例如,我需要每0.5秒处理一个文件。 第一个任务开始处理文件,0.5秒后如果第一个线程没有完成第二个线程产生并开始处理第二个文件,依此类推。 这可以通过以下方式完成:

    ScheduledExecutorService executor = Executors.newScheduledThreadPool(4)
    while (!executor.isShutdown()) {  
        executor.execute(task);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            // handle
        }
    }

现在我的问题:为什么我不能用executor.scheduleAtFixedRate来做?

我得到的是,如果第一个任务需要更长时间,第二个任务会在第一个任务完成后立即启动,但即使执行程序具有线程池,也不会启动新线程。 executor.scheduleWithFixedDelay是明确的 - 它执行它们之间具有相同时间跨度的任务,并且完成任务所需的时间并不重要。 所以我可能误解了ScheduledExecutorService用途。

也许我应该看看另一种执行者? 或者只使用我在这里发布的代码? 有什么想法吗?

我已经通过在每个计划的执行中启动嵌套的匿名runnable来解决了这个问题:

final ScheduledExecutorService service = Executors.newScheduledThreadPool(POOL_SIZE);

final Runnable command = new SlowRunnable();

service.scheduleAtFixedRate(
    new Runnable() {
      @Override
      public void run() {
        service.execute(command);
      }
    }, 0, 1, TimeUnit.SECONDS);

在这个例子中,将有一个线程在每个间隔执行一个快速指令,所以当下一个间隔到期时它肯定会完成。 剩余的POOL_SIZE-1线程将并行执行SlowRunnable的run(),这可能比单个时间间隔的持续时间更长。

请注意,虽然我喜欢这个解决方案,因为它最小化代码并重用相同的ScheduledExecutorService,但它必须正确调整大小并且可能无法在每个上下文中使用:如果SlowRunnable非常慢以至于POOL_SIZE作业一起执行,那么没有线程可以及时运行计划任务。

此外,如果您将间隔设置为1 TimeUnit.NANOSECONDS,那么主runnable的执行可能会变得太慢。

其中一个scheduleAtFixedRate方法就是您正在寻找的方法。 它以给定的间隔从池中的线程中启动任务,即使先前的任务尚未完成。 如果您没有线程来执行处理,请调整池大小约束,如ThreadPoolExecutor文档中所述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM