来自:http://www.cnblogs.com/taven/archive/2011/12/17/2291466.html
1 import java.util.concurrent.Callable; 2 3 import java.util.concurrent.ExecutorService; 4 5 import java.util.concurrent.Executors; 6 7 import java.util.concurrent.Future; 8 9 10 11 /** 12 13 从本节开始,主要介绍J2SE5.0与线程相关的新特性,新的线程类主要集中在java.util.concurrent 14 15 包中,本节实例将介绍如何使用java.util.concurrent.Callable和java.util.concurrent.Future类, 16 17 用Callable定义一个任务并启动它,然后用它的Future获取输出结果并停止它. 18 19 关键技术剖析: 20 21 关于Callable和Future类的关键技术如下: 22 23 1.Callable是类似于Runnable的接口,实现Callable接口的类和实现Runable的类都是可被其他线程 24 25 执行的任务. 26 27 2.Callable和Runnable的区别如下: 28 29 1)Callable定义的方法是call,而Runnable定义的方法是run. 30 31 2)Callable的call方法可以有返回值,而Runnable的run方法不能有返回值 32 33 3)Callable的call方法可抛出异常,而Runnable的run方法不能抛出异常 34 35 3.Future表示异步计算的结果,它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的 36 37 结果.Future的cancel方法取消任务的执行,有一个布尔参数,参数为true表示立即中断任务的执行,参数 38 39 为false表示允许正在运行的任务运行完成.Future的get方法等待计算完成,获取计算结果. 40 41 */ 42 43 public class CallableAndFuture { 44 45 /**自定义一个任务类,实现Callable接口*/ 46 47 public static class MyCallableClass implements Callable{ 48 49 private int flag = 0; 50 51 public MyCallableClass(int flag){ 52 53 this.flag = flag; 54 55 } 56 57 public String call() throws Exception{ 58 59 if(this.flag == 0){ 60 61 return "flag = 0";//如果flag的值为0,则立即返回 62 63 } 64 65 if(this.flag == 1){ 66 67 //如果flag的值为1,做一个无限循环 68 69 try{ 70 71 while(true){ 72 73 System.out.println("looping..."); 74 75 Thread.sleep(2000); 76 77 } 78 79 }catch(InterruptedException e){ 80 81 System.out.println("Interrupted"); 82 83 } 84 85 return "false"; 86 87 }else{ 88 89 throw new Exception("Bad flag value!");//flag不为1或0,则抛出异常 90 91 } 92 93 } 94 95 } 96 97 public static void main(String... args){ 98 99 //定义3个Callable类型的任务 100 101 MyCallableClass task1 = new MyCallableClass(0); 102 103 MyCallableClass task2 = new MyCallableClass(1); 104 105 MyCallableClass task3 = new MyCallableClass(2); 106 107 108 109 //创建一个执行任务的服务 110 111 ExecutorService es = Executors.newFixedThreadPool(3); 112 113 try{ 114 115 //提交并执行任务,任务启动时返回了一个Future对象 116 117 //如果想得到任务执行的结果或者是异常可对这个Future对象进行操作 118 119 Future future1 = es.submit(task1); 120 121 //获得第一个任务的结果,如果调用get方法,当前线程会等待任务执行完毕后才往下执行 122 123 System.out.println("task1: " + future1.get()); 124 125 126 127 Future future2 = es.submit(task2); 128 129 //等待5秒后,再停止第二个任务,因为第二个任务进行的是无限循环 130 131 Thread.sleep(5000); 132 133 System.out.println("task2 cancel: " + future2.cancel(true)); 134 135 136 137 //获取第三个任务的输出,因为执行第三个任务会引起异常 138 139 //所以下面的语句将引起异常的输出 140 141 Future future3 = es.submit(task3); 142 143 System.out.println("task3: " + future3.get()); 144 145 }catch(Exception e){ 146 147 System.out.println(e.toString()); 148 149 } 150 151 es.shutdown();//立即停止任务执行服务 152 153 } 154 155 } 156 157