Java并发编程实践 目录
并发编程 04—— 闭锁CountDownLatch 与 栅栏CyclicBarrier
并发编程 06—— CompletionService : Executor 和 BlockingQueue
并发编程 10—— 任务取消 之 关闭 ExecutorService
并发编程 12—— 任务取消与关闭 之 shutdownNow 的局限性
并发编程 13—— 线程池的使用 之 配置ThreadPoolExecutor 和 饱和策略
概述
第1部分 问题引入
如果外部代码能在某个操作正常完成之前将其置入“完成”状态,那么这个操作就可以称为可取消的。
在java中没有一种安全的抢占式方式来停止线程,因此也就没有安全的抢占式方法来停止任务。只有一些协作式的机制,使请求取消的任务和代码都遵循一种协商好的协议。
其中一种协作机制能设置某个“已请求取消”标志,而任务将定期地查看该标志。如果设置了这个标志,那么任务将提前结束。
第2部分 实例
下面程序,其中PrimeGenerator 持续地枚举素数,直到它被取消。cancel方法将设置cancelled标志,并且主循环在搜索下一个素数之前会首先检查这个标志。(为了使这个过程能可靠地工作,标志cancelled必须为volatile类型)
1 package com.concurrency.CancellationAndShutdown_7; 2 3 import java.math.BigInteger; 4 import java.util.ArrayList; 5 import java.util.List; 6 7 import net.jcip.annotations.GuardedBy; 8 9 /** 10 * 使用volatile 类型的域来保存取消状态 11 * @ClassName: PrimeGenerator 12 * @author Xingle 13 * @date 2014-9-24 下午3:05:08 14 */ 15 public class PrimeGenerator implements Runnable{ 16 17 @GuardedBy("this") 18 private final List<BigInteger> primes = new ArrayList<BigInteger>(); 19 20 private volatile boolean cancelled; 21 22 @Override 23 public void run() { 24 BigInteger p = BigInteger.ONE; 25 while(!cancelled){ 26 //返回下一个大于p的素数 27 p = p.nextProbablePrime(); 28 synchronized (this) { 29 primes.add(p); 30 31 } 32 } 33 } 34 35 public void cancel(){ 36 cancelled = true; 37 } 38 39 public synchronized List<BigInteger> get(){ 40 return new ArrayList<BigInteger>(primes); 41 } 42 43 }
测试程序:
1 package com.concurrency.CancellationAndShutdown_7; 2 3 import java.math.BigInteger; 4 import java.util.List; 5 6 7 /** 8 * 测试程序—— 运行100ms时间的素数生成器 9 * @ClassName: PrimeGeneratorMain 10 * @author Xingle 11 * @date 2014-9-24 下午5:23:44 12 */ 13 public class PrimeGeneratorMain { 14 15 public static void main(String[] args){ 16 PrimeGenerator generator = new PrimeGenerator(); 17 new Thread(generator).start(); 18 try { 19 Thread.sleep(100); 20 } catch (InterruptedException e) { 21 e.printStackTrace(); 22 } finally { 23 generator.cancel(); 24 } 25 List<BigInteger> ls = generator.get(); 26 for(int i= 0;i<ls.size();i++){ 27 System.out.println(ls.get(i)); 28 } 29 } 30 }
执行结果:
1.《并发编程实战》