多线程进阶004 之 任务取消(一)
来源:互联网 发布:掌上电力提示网络异常 编辑:程序博客网 时间:2024/05/22 17:34
如果外部代码能在某个操作正常完成之前将其置入”完成”状态,那么这个操作就可以称为可取消的,取消某个操作的原因有很多:
用户请求取消: 用户点击图形界面程序中的”取消”按钮,或者通过管理接口来发出取消请求.
有时间限制操作:例如,某个应用程序需要在有限时间内搜索问题空间,并在这个时间内选择最佳的解决方案.当计时器超时时,需要取消所有正在搜索的任务.
应用程序事件: 例如,应用程序对某个问题空间进行分解并搜索,从而使不同任务都可以搜索问题空间中的不同区域.当其中一个任务找到了解决方案时,其他所有的任务都将被取消.
错误: 网页爬虫程序搜索相关页面,并将页面或摘要数据保存到硬盘,当一个爬虫任务发生错误时,那么所有的搜索任务都会取消,此时有可能会记录它们当前状态,以便稍后启动.
关闭: 当一个程序或服务关闭时,必须对正在处理和等待处理的工作执行某种操作,在平缓关闭过程中,当前正在执行的任务将继续执行直到完成,而在立即关闭的过程中,当前任务则有可能取消.
使用volatile类型自定义取消
import java.math.BigInteger;import java.util.ArrayList;import java.util.List;public class PrimeGenerator implements Runnable{ private final List<BigInteger> primes = new ArrayList<BigInteger>(); private volatile boolean cancelled; @Override public void run() { BigInteger p = BigInteger.ONE; while(!cancelled){ p = p.nextProbablePrime(); synchronized (this) { primes.add(p); } } } public void cancel(){ cancelled = true; } public synchronized List<BigInteger> get(){ return new ArrayList<BigInteger>(primes); }}
一个仅运行一秒钟的素数生成器
static List<BigInteger> aSecondOfPrimes() throws InterruptedException{ PrimeGenerator generator = new PrimeGenerator(); new Thread(generator).start(); try{ Thread.sleep(1000); }finally{ generator.cancel(); } return generator.get(); }
不可靠的取消操作将把生产者置于阻塞操作中
PrimeGenerator中的取消机制最终会使得搜索素数的任务退出,但在退出过程中需要花费一定的时间,然而,如果使用这种方法的任务调用了一个阻塞方法,例如BlockingQueue.put,那么可能会产生一个更严重的问题,任务永远不会检查取消标志,因此永不结束.
public class BrokenPrimeProducer extends Thread{ private final BlockingQueue<BigInteger> queue; private volatile boolean cancelled; BrokenPrimeProducer(BlockingQueue<BigInteger> queue){ this.queue = queue; } @Override public void run() { BigInteger p = BigInteger.ONE; try{ while(!cancelled){ /** * 当队列满了的时候 * 生产者阻塞,如果要取消任务, * 调用cancel()这个方法是无法做到的, * 如果消费者消费过慢,或者是迟迟不消费, * 那么该任务就需要阻塞很久,直到消费者消费完毕才能取消. */ queue.put(p = p.nextProbablePrime()); } }catch(InterruptedException e){} } public void cancel(){ cancelled = true; } static void consumePrimes(BlockingQueue<BigInteger> primes) throws InterruptedException{ BrokenPrimeProducer producer = new BrokenPrimeProducer(primes); producer.start(); try{ while(needMorePrimes()){ consume(primes.take()); } }finally{ producer.cancel(); } } private static void consume(BigInteger take) { /** * 假设消费时间很长很长 */ } private static boolean needMorePrimes() { return false; }}
中断是实现取消最合理的方式
理解: 它并不会真正中断一个正在运行的线程,而只是发出中断请求,然后由线程在下一个合适的时刻中断自己.
public class PrimeProducer extends Thread{ private final BlockingQueue<BigInteger> queue; PrimeProducer(BlockingQueue<BigInteger> queue){ this.queue = queue; } @Override public void run() { try{ BigInteger p = BigInteger.ONE; /** * 这里并不一定需要显式的检测, * 但执行检测却会使PrimeProducer对中断具有更高的响应性 */ while(!Thread.currentThread().isInterrupted()) queue.put(p = p.nextProbablePrime()); }catch(InterruptedException e){ /** * 允许线程退出 */ } }}
阅读全文
1 0
- 多线程进阶004 之 任务取消(一)
- 多线程进阶005 之 任务取消(二)
- 多线程编程:任务取消
- 我之见--java 多线程任务的取消
- 多线程编程:任务取消,中断
- 【java总结】多线程进阶篇之任务执行
- 多线程进阶001 之 在线程中执行任务
- 多线程进阶代码一
- 多线程菜鸟进阶 一
- 多线程进阶(一)
- [VB.NET]多线程——取消任务
- 多线程进阶之二
- 多线程进阶之三
- 多线程编程之线程取消
- 多线程之定时器任务
- python里创建任务执行一半时取消任务执行
- Java 并发编程之任务取消
- Java之旅--多线程进阶
- Rails 中的 Asset Pipeline
- PyTorch学习系列(十四)——保存训练好的模型
- jquery validate 自定义验证表单隐藏域
- Cocos2d-X游戏开发(三)
- 循环删除LISTBOX的项目
- 多线程进阶004 之 任务取消(一)
- redis面试摘录(收录待完善)
- MAC,PIN密钥体系
- Python~~简介介绍
- linux内核(0.11)
- 算法
- No services have been found解决方案
- Intent.ACTION_VIEW
- myeclipse的智能提示