Loading

Java并发学习之任务取消策略

一.任务取消概述

1.我们为什么需要取消任务?

任务和线程的启动很容易,在大多数时候,我们都希望它运行直到结束。然而有时候我们需要提前结束任务或线程,原因可能是用户取消了操作,可能是应用程序需要被快速关闭。

2.如何取消任务?
要使任务和线程能安全,快速,可靠地停下来并不是一件很容易的事情。
Java没有提供任何机制来安全地终止线程,但是它提供了中断(Interruption),这是一种协作机制,能够使一个线程终止另一个线程的当前工作。

3.协作机制的必要性
这种协作机制是非常必要的,我们很少希望某个任务,线程或服务立即停止,因为这种立即停止会使共享的数据结构处于不一致的状态。
相反,在编写任务和服务时可以使用一种协作的方式:当需要停止时,它们首先会清除当前正在执行的工作,然后再结束。 这提供了更好的灵活性,因为任务本身的代码比发出取消请求的代码更清楚如何执行清除工作。

4.生命周期结束的问题会使任务,服务,程序的设计和实现等过程变得复杂,而这个在程序设计中非常重要的要素却经常被忽略。

一个在行为良好的的软件与勉强能运行的软件之间的区别在于:行为良好的软件能很完善地处理失败,关闭和取消等过程。

二.正式学习任务取消

1.如果外部代码能在某个操作正常完成之前将其置入 “ 完成 ” 状态,那么这个操作就可以被称为可取消的(Cancellable)
取消某个操作的原因有很多:
1)用户取消请求。 比如用户点击图像界面中的取消按钮。

2)有时间限制的操作。 例如某个应用程序需要在有限的时间内搜索问题空间,并在这个时间内选择最佳解决方案,当计时器超时时,需要取消所有正在执行的搜索任务。

3)应用程序事件。例如应用程序对某个问题空间进行分解并搜索,从而使不同的任务可以搜索问题空间中的不同区域。当其中一个任务找到了解决方案时,所有其他还在执行的任务都将被取消。

4)错误。例如网页爬虫程序搜索相关的页面,并将页面或摘要数据保存到硬盘,当一个爬虫任务发生错误时(比如磁盘空间满了),那么所有任务将被取消,此时可能会记录它们的当前状态,以便稍后重新启动。

5)关闭。当一个程序或服务关闭时,必须对正在处理和等待处理的工作执行某种操作。在平缓的关闭过程中,当前正在执行的任务将继续执行直到完成,而在立即关闭过程中,当前的任务则可能取消。

2.Java中如何停止任务:
在Java中没有一种安全的抢占式方法来停止线程,因此也就没有安全的抢占式方法来停止任务。
在Java中只有一些协作式的机制,使请求取消的任务和代码都遵循一种商议好的协议。

1)通过设置一个 “ 已请求取消” 的标志来结束任务

实例:

public class PrimeGenerator implements Runnable{
   
    private final List<Biginteger> primes = new ArrayList<BigInteger>();
    private volatile boolean cancelled;//声明已请求取消标志
    
    //默认情况下cancelled为false,所以这个任务会一直执行下去
    //只有当外部调用了cancel方法它才会结束
    public void run(){
   
      BigInteger p = BigInteger.ONE;
      while(!cancelled){
   
       p = p.nextProbablePrime();
       synchronized(this){
   
         primes.
posted @ 2020-11-20 14:46  文牧之  阅读(63)  评论(0)    收藏  举报  来源