Java 并发编程之任务取消

任务取消

取消分为如下几种:

  • 用户请求取消
  • 有时间限制的操作
  • 应用程序事件
  • 错误
  • 关闭

在我看到了几个开源项目中是这样的:

都是在public void run()方法内,用if判断Canceled状态。这个Canceled一般是布尔类型。并用Volatile声明,它可以确保可见性,但不能确保原子性。这个就允许其它线程对正在运行的线程执行取消操作。比如支付宝中,如果余额不足那么取消支付操作。这个是when 和what ,剩下的就是how to cancel。这些流程和保证放在一起就构成了支付的取消策略


中断

在阻塞方法中慎重使用取消操作。因为有可能方法被阻塞导致永远不能检查取消标志。

比如一个BlockingQueue<BIgInterger>类型

public void run(){
try{
BigInteger P =BigInteger.ONE;
while(!cancelled)
	queue.put(P=P.nextProbablePrime());
}catch(InterruptedException consumed){}

}
BlockingQueue为阻塞队列,他的put方法也是阻塞方法。当队列满了的时候,put被阻塞,此时消费者发送取消生产了。然后如果队列一直是满的。这个生产者将会一直阻塞在Put方法上不会有机会去检查是否被取消。

每个线程都有一个boolean类型的中断状态,当中断线程时,这个线程的中断状态将会被 设置为true,如Thread.sleep和Object.wait()都会检查线程何时中断。并且在发现中断时提前返回。

调用interrupt并不意味着立即停止目标线程正在进行的工作,而只是传递了请求中断的消息。通常中断是实现取消的最合理方法。


所以上面的那个 错误示例可改正如下

public void run(){
try{
BigInteger P =BigInteger.ONE;
while(!Thread.currentThread().isInterrupted())
	queue.put(P=P.nextProbablePrime());
}catch(InterruptedException consumed){}
//允许线程退出
}

响应中断

比如我们在创建一个File类的时候 或者 一个Socket的时候 经常会提示我们必须要加Try catch 或者throwsexception。可能一般只是为了代码格式选择一下,并不会做什么异常处理,其实异常处理是一个很重要的步骤,Throwsexception是在方法后加上throws Exception 这个的作用是将异常传递到调用它的那个 方法 ,然后最终需要有一个方法try catch处理异常,当然这没有硬性的规定,即使你一直throws到main方法也未尝不可。

只有实现 了线程中断策略的代码才可以屏蔽中断请求,在常规的任务和库代码中都不应该屏蔽中断请求


有一种方法可以使线程在退出之前恢复中断,用在一些不可以退出的必要线程中。


public Task getNextTask(BlockingQueue<Taskgt;queue>){
boolean interrupted=false;
try{
	while(true){
		try{
			return queue.take();
		}
		catch(InterruptedException e){
		 interrupted=true;
		 //重试
		}
	}
	finally{
		if(interrupted)
			Thread.currentThread().interrupted();
	}
}
}











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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值