开发者

ScheduledExecutorService multiple threads in parallel

开发者 https://www.devze.com 2023-03-23 12:59 出处:网络
I\'m interested in using ScheduledExecutorService to spawn mu开发者_如何学运维ltiple threads for tasks if task before did not yet finish. For example I need to process a file every 0.5s. First task st

I'm interested in using ScheduledExecutorService to spawn mu开发者_如何学运维ltiple threads for tasks if task before did not yet finish. For example I need to process a file every 0.5s. First task starts processing file, after 0.5s if first thread is not finished second thread is spawned and starts processing second file and so on. This can be done with something like this:

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

Now my question: Why I can't do it with executor.scheduleAtFixedRate?

What I get is if the first task takes longer, the second task is started as soon as first finished, but no new thread is started even if executor has pool of threads. executor.scheduleWithFixedDelay is clear - it executes tasks with same time span between them and it doesn't matter how long it takes to complete the task. So probably I misunderstood ScheduledExecutorService purpose.

Maybe I should look at another kind of executor? Or just use code which I posted here? Any thoughts?


I've solved the problem by launching a nested anonymous runnable in each scheduled execution:

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);

With this example there will be 1 thread executing at every interval a fast instruction, so it will be surely be finished when the next interval is expired. The remaining POOL_SIZE-1 threads will be executing the SlowRunnable's run() in parallel, which may take longer time than the duration of the single interval.

Please note that while I like this solution as it minimize the code and reuse the same ScheduledExecutorService, it must be sized correctly and may not be usable in every context: if the SlowRunnable is so slow that up to POOL_SIZE jobs get executed together, there will be no threads to run the the scheduled task in time.

Also, if you set the interval at 1 TimeUnit.NANOSECONDS it will probably became too slow also the execution of the main runnable.


One of the scheduleAtFixedRate methods is what you're looking for. It starts a task in a thread from the pool at the given interval, even if previous tasks haven't finished. If you're running out of threads to do the processing, adjust the pool size constraints as detailed in the ThreadPoolExecutor docs.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号