并发编程 07—— 任务取消 第1部分 问题引入 第2部分 实例

概述

第1部分 问题引入

第2部分 实例

参考

  如果外部代码能在某个操作正常完成之前将其置入“完成”状态,那么这个操作就可以称为可取消的。

  在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 }

执行结果:

并发编程 07—— 任务取消
第1部分 问题引入
第2部分 实例


参考:

1.《并发编程实战》