Java并行开发笔记4

不可靠的取消操作将把生产者置于阻塞的操作中

 

	class BrokenPrimeProducer extends Thread{
		private final BlockingQueue<BigInteger> queue;
		private volatile boolean cancelled = false;
		
		BrokenPrimeProducer(BlockingQueue<BigInteger> queue){
			this.queue = queue;
		}
		
		public void run(){
			try{
				BigInteger p = BigInteger.ONE;
				while(!cancelled)
					queue.put(p = p.nextProbablePrime());
			}catch(InterruptedException consumed){
				
			}
		}
		
		public void cancel(){ cancelled = true;}
	}
	
	void consumePrimes() throws InterruptedException {
		BlockingQueue<BigInteger> primes = ...;
		BrokenPrimeProducer producer = new BrokenPrimeProducer(primes);
		producer.start();
		try{
			while(needMorePrimes()){
				consume(primes.take());
			}
		}finally{
			producer.cancel();
		}
	}

 上述代码中,生产者线程生成素数,并将它们放入一个阻塞队列。如果生产者的速度超过了消费者的处理速度,队列将被填满,put方法也会阻塞。当生产者在put方法中阻塞时,如果消费者希望取消生产任务,那么将发生什么情况?它可以调用cancel方法来设置cancelled标志,但此时生产者却永远不能检查这个标志,因为它无法从阻塞的put方法中恢复过来(因为消费者此时已经停止从队列中取出素数,所以put方法将一直保存阻塞状态)。

  为了解决上述问题,可通过线程中断代替取消操作,具体代码如下:

class BrokenPrimeProducer extends Thread{
		private final BlockingQueue<BigInteger> queue;
		
		BrokenPrimeProducer(BlockingQueue<BigInteger> queue){
			this.queue = queue;
		}
		
		public void run(){
			try{
				BigInteger p = BigInteger.ONE;
				while(!Thread.currentThread().isInterrupted())
					queue.put(p = p.nextProbablePrime());
			}catch(InterruptedException consumed){
				
			}
		}
		
		public void cancel(){ interrupt();}
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值