想想这个
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());
程序打印的结果为:ited=true。但是如果在取消之前调用shutdown(即第5行注解,第9行注解),那么程序将打印isterminated=false;不过,如果您也调用purge(即第8行中的comment),那么它将输出isterminated=true。
这是预期行为还是错误?
1条答案
按热度按时间q3aa05251#
预期行为:
场景1:您取消了未来的任务,然后适当地关闭,然后等待终止,所以您遵循了命令。任务将取消,等待终止将成功,因为它将在超时之前完成。
场景2:你关机,不取消。在这种情况下,waitingtermination将为false,因为并非所有任务都已完成/和/或取消,它将超时并返回false。
关闭,取消,清除,等待终止。实际上,您最终删除了所有已取消的任务,而awaittermination将成功,而isterminated将返回true,如本例所示(所有任务都已完成)
您还可以查看awaittermination是否返回true/false,以及是否在调用shutdown()之后执行器有机会完成之前实际超时。
请参阅每种方法的清晰文档以及它们的作用。
布尔值()
如果关闭后所有任务都已完成,则返回true。请注意,除非先调用shutdown或shutdownnow,否则isterminated永远不会为true。
返回:如果关闭后所有任务都已完成,则返回true
这意味着它只会在(所有)计划任务完成时返回true,简单地调用shutdown不会返回true。
公共布尔等待终止(长超时,timeunit)引发interruptedexception
从接口复制的说明:executorservice阻塞,直到所有任务在关闭请求后完成执行,或者发生超时,或者当前线程中断,以先发生的为准。
参数:timeout-等待的最大时间单位-timeout参数的时间单位返回:如果此执行器终止,则返回true;如果终止前超时已过,则返回false抛出:interruptedexception-如果在等待时中断
public void purge()
尝试从工作队列中删除所有已取消的未来任务。此方法可以用作对功能没有其他影响的存储回收操作。取消的任务永远不会执行,但可能会在工作队列中累积,直到工作线程可以主动删除它们。而调用此方法会尝试现在删除它们。但是,如果存在其他线程的干扰,此方法可能无法删除任务。