java 取消任务

是什么?为什么?怎么做?

 

一、是什么

线程执行器支持取消任务。可以中断正在执行的任务(中断的方式),也可哟直接取消未执行的任务(直接取消执行计划)。

二、为什么

1.取消任务的情景

任务超时、任务报错之后主动取消、因为一些特殊的原因任务没有必要继续执行了,在这些场景中有必要主动取消任务。

主动取消任务,可以有效腾出资源,避免无效操作。

2.错误的取消方式

记得之前写过这样一个情景:

线程的超时处理。线程超时后,关闭线程。

这样写是有问题的。如果一条任务超时,就应该单独结束那条任务(在线程执行器中的每个任务,都会有自己的任务对象,使用取消方法就可以了),而不是直接关闭整个scheduledExecutorService,影响到所有任务的执行。

三、怎么做

如果想取消一个任务,可以使用Future接口的cancle方法。根据调用cancle方法时所传递的参数以及任务的状态,这个方法的行为有些不同。

如果任务已经完成,或者之前已经被取消,或者由于某种原因而不能被取消,那么方法将返回false,并且任务不能取消。

如果任务在执行器中等待分配Thread对象来执行它,那么任务被取消,并且不会开始执行。

如果任务已经在执行,那么结果取决于调用cancle方法时传递的参数。如果传递的参数为true,并且任务正在运行,那么任务将被取消。如果传递的参数为false并且任务正在运行,那么任务不会被取消。

1.取消正在运行的任务

运行结果:

如果cancel的参数为true,那么线程会被中断,try catch捕获中断错误,cancel方法返回true。如果cancel的参数为false,那么线程无法被中断,cancel方法返回false。

2.取消延时任务

(1)取消还未开始执行的的延时任务

运行结果:

如果任务在执行器中等待分配Thread对象来执行它,那么任务被取消,并且不会开始执行。

(2)取消正在运行的延时任务

运行结果:

如果cancel的参数为true,那么线程会被中断,try catch捕获中断错误,cancel方法返回true。如果cancel的参数为false,那么线程无法被中断,cancel方法返回false。

3.取消周期任务

(1)取消还未开始执行的周期任务

运行结果:

这里需要解释一下这个运行结果。future2在执行之前就已经被取消了,所以每次都只有一条输出,证明只有一个任务在运行(实际上可以通过isCancelled方法来确认线程的状态是否被取消)。

ScheduledThreadPoolExecutor在执行任务时,每次都会从线程池中选择一条空闲的线程,所以每次执行周期任务的线程都有可能不同,这就是线程名称经常变化的原因。

如果任务在执行器中等待分配Thread对象来执行它,那么任务被取消,并且不会开始执行。

(2)取消正在运行的周期任务

运行结果:

如果cancel的参数为true,那么线程会被中断,try catch捕获中断错误,cancel方法返回true。如果cancel的参数为false,那么线程无法被中断,cancel方法返回false。

四、总结

要体会到ScheduledThreadPoolExecutor的优点。

发表评论

电子邮件地址不会被公开。 必填项已用*标注