ScheduledExecutorService等待任务完成,未完成的任务是否堆积起来最终最终中断了主任务?

时间:2020-06-19 19:07:08

标签: java scheduledexecutorservice

我对我使用ScheduledExecutorService的新实现感到好奇,在该实现中,任务预计将在100ms周期和0ms延迟内完成。但是,如果有系统负载,并且要花费550毫秒,那么ScheduledExecutorService是否会为这4个待处理任务维护一个队列?然后(第一个延迟为0ms)第一个完成后运行。如果第二次执行需要560 ms的时间,那还会在队列中再增加4个线程吗?

没有关于它的文档,否则我可能会忽略它。但是,我想确保大量此类执行会触发泄漏或溢出。

例如:在下面的代码中,主线程会失败吗?

    private static ScheduledExecutorService consumerThreadPool = Executors.newSingleThreadScheduledExecutor();
    public static void main(String[] args) throws Exception {
        consumerThreadPool.scheduleAtFixedRate(() -> performTask(), 0, 1, TimeUnit.MILLISECONDS);
    }

    private static void performTask () {
        try {
            Thread.sleep(550);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

1 个答案:

答案 0 :(得分:0)

如果任务超出下一个预定时间,则将跳过它们,您可以使用System.out.println轻松验证并将睡眠时间从500ms更改为5000ms:

public static void main(final String[] args) throws InterruptedException, ExecutionException
{
    var executor = Executors.newScheduledThreadPool(1);
    var count = new AtomicInteger();

    Runnable task = () -> {
        String desc = "run("+((System.currentTimeMillis() / 1000) % 60)+") "+Thread.currentThread().getName()+" count "+count.incrementAndGet();
        System.out.println(desc);
        if(count.get() == 50)
            throw new RuntimeException("I give up!");

        try
        {
            Thread.sleep(2500);
        }
        catch (InterruptedException e)
        {
            System.out.println("Thread "+Thread.currentThread().getName()+" INTERRUPTED");
        }
    };
    var future = executor.scheduleAtFixedRate(task, 5000, 1000, TimeUnit.MILLISECONDS);

    System.out.println("Calling future.get() ...");
    try {
        var res = future.get();
        System.out.println("future.get()="+res);
    }
    catch(Exception e)
    {
        System.err.println("There was an exception:" +e);
        // Decide between "continue" or "throw e" here
        // ...
    }
    executor.shutdownNow();
    System.out.println("shutdown complete");
}