考虑一下这个
LongAdder count = new LongAdder();
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
var future1 = executor.schedule(count::increment, 1800, TimeUnit.MILLISECONDS);
var future2 = executor.schedule(count::increment, 1900, TimeUnit.MILLISECONDS);
//executor.shutdown(); // line 5
System.out.println(future1.cancel(true));
System.out.println(future2.cancel(true));
//executor.purge();
executor.shutdown(); // line 9
executor.awaitTermination(1600, TimeUnit.MILLISECONDS);
System.out.println("isTerminating=" + executor.isTerminated());
System.out.println("terminated=" + executor.isTerminated());
System.out.println("count=" + count.intValue());该程序打印isTerminated=true。但是如果您在cancel之前调用shutdown (即第5行注释,第9行注释),那么程序将打印isTerminated=false;但是如果您还调用了purge (即第8行注释),那么它将打印出isTerminated=true。
这是预期行为还是bug?
发布于 2020-12-03 05:24:55
预期行为:
场景1:您取消了未来的任务,然后适当地关闭,然后等待终止,因此您遵循了顺序。任务将取消,awaitTermination将成功,因为它将在超时之前完成。
场景2:您关闭了,但没有取消。在这种情况下,awaitingTermination将为false,因为并非所有任务都已完成/和/或/取消,它将超时并返回false。
场景3:关机,取消,清除,awaitTermination。实际上,您最终删除了所有取消的任务,awaitTermination会成功,isTerminated会像本例一样返回true (所有任务都已完成)
您还可以查看awaitTermination是否返回true/false,以查看在调用shutdown()后exector有机会完成之前是否实际超时。
System.out.println(executor.awaitTermination(1600, TimeUnit.MILLISECONDS));请参阅这些方法的详细文档以及它们的作用。
布尔型isTerminated()
如果关机后所有任务都已完成,则
返回true。请注意,除非首先调用shutdown或shutdownNow,否则isTerminated永远不会为真。
返回:如果关机后所有任务都已完成,则返回true
这意味着它只会在(所有)计划任务完成时返回true,简单地调用shutdown不会返回TRUE。
公共布尔值awaitTermination(长超时,TimeUnit单位)抛出InterruptedException
从接口复制的
描述: ExecutorService阻塞,直到所有任务在关机请求后完成执行,或者发生超时,或者当前线程被中断,以先发生的为准。
参数: timeout -最长等待时间单位- timeout参数的时间单位返回:如果此执行程序终止,则返回true;如果在终止之前超时,则返回false : InterruptedException -如果等待时被中断
public void ()
尝试从工作队列中删除所有已取消的未来任务。此方法可用作对功能没有其他影响的存储回收操作。取消的任务永远不会执行,但可能会在工作队列中累积,直到工作线程可以主动删除它们。现在调用此方法会尝试删除它们。但是,在存在其他线程干扰的情况下,此方法可能无法删除任务。
https://stackoverflow.com/questions/65115866
复制相似问题