并发编程(二)取消和关闭

java没有提供任何机制来安全的终止线程(Thread.stop  Thread.suspend存在严重缺陷),提供了中断,一种写作机制,能够使一个线程终止另一个线程的当前工作。

任务取消:

如果外部代码能在某个操作正常完成之前将其置入“完成”状态,那么就是可取消的(cancellable)

取消策略:

一个可取消的任务必须拥有取消策略。

how  其他代码如何请求取消该任务

when 任务在何时检查是否已经请求了取消

what 响应取消请求应该执行哪些操作

一种简单的取消策略

public class PrimeGenerator implements Runnable{
private final List<BigInteger> primes=new ArrayList<BigInteger>();
private volatile boolean cancelled;

public void run(){
	BigInteger pBigInteger=BigInteger.ONE;//  为1
	while(!cancelled){
		pBigInteger=pBigInteger.nextProbablePrime();
		synchronized (this) {
			primes.add(pBigInteger);
		}
	}
}

public void cancel(){cancelled=true;}

public synchronized List<BigInteger> get(){
	return new ArrayList<BigInteger>(primes);
}

}
定义取消标志位  volatile boolean cancelled

定义取消方法 void cancell()

在run()方法中合适位置检查标志位,有无被其他线程置true

缺点:在检查取消标志之前,存在阻塞的方法,可能永远都不会检查这个标志位

中断取消:

public class primeProducer extends Thread{
private final BlockingQueue<BigInteger> queue;

public primeProducer(BlockingQueue<BigInteger> queue) {
	// TODO Auto-generated constructor stub
	this.queue=queue;
}
public void run(){
	try{
		BigInteger pBigInteger=BigInteger.ONE;
		while(!Thread.currentThread().isInterrupted())
			queue.put(pBigInteger=pBigInteger.nextProbablePrime());
	   }
	catch(InterruptedException consumed){
		
	}
}
public void cancel(){interrupt();}
}
1、阻塞库方法(thread.sleep  object.wait等)检查线程何时中断,并在发现中断时提前返回

操作:清除中断状态,抛出interruptedException

2、线程在非阻塞状态下中断时,它的中断状态将被设置,如果不触发interruptedException,中断状态将一直保持

while(!Thread.currentThread().isInterrupted()){ //检查中断状态

中断并不会真正的中断一个线程,他仅仅是发出了一个 中断请求,线程收到请求后可以选择处理,也可以选择不处理。系统的有些库函数(阻塞的方法)会关注这个状态,并在接到中断之后抛出异常
注意:中断请求最好不要隐藏。静态的interrupted方法会清除中断状态,因此,如果interrupted方法返回true,可以抛出异常或者是再次调用interrupt方法设置中断状态
中断策略:
          决定如何应对中断请求:尽可能迅速退出,如果需要的话进行清理,可能的话通知其他的实体本线程退出。
在任务代码中应该小心的保存中断状态,因为线程不是隶属于该任务的,对于线程池来讲,一个线程上可能会运行多个任务,任务中小心的保存中断状态,线程的所有者才能最终有所作用。
 
对于大多数可阻塞的库函数而言,他们之所以仅仅抛出了InterruptedException,是因为他们知道自己没有权限结束一个本来就不属于他们的线程,所以抛出异常,传给上层代码进一步的决定要采取的策略。在捕获了InterruptedException之后,要恢复中断的状态
Thread.currentThread().interrupt();

响应中断
     在调用可中断的阻塞函数时 的策略
    1.传递异常,这时你的方法也成为可中断的阻塞方法了
        public void sleep(int i) throws  InterruptedException{
            Thread.sleep(i);
        }
    2.保存中断状态,上层调用者对其处理
        在catch语句中回复中断状态 --Thread.currentThread().interrupt()
    3.实现含有阻塞方法的不可取消任务
        一般来说,含有阻塞方法的任务均可响应中断,可以通过特殊的处理,使任务在退出前保存中断
        定义一个自有的中断状态,当阻塞的方法响应中断抛出异常时,catch中把自有的中断状态设置为ture,然后在finally块中检查这个自有的中断状态,然后设置Thread 的中断状态。这样只有在任务结束退出的时候才设置的Thread的中断。实现了不可取消的任务。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值