之前工作中也有使用过Callable,但是却没有使用Thread对象去操作过,今晚 小组培训,涨知识了,现特意记录一下,以免忘记.
先看一下Thread的构造器
可以看到,Thread类并没有提供参数是Callable的构造器, 但是Runnable是有的.
再看下面类关系图
所以,我们在使用Thread对象操作Callable实例时,完全可以使用FutureTask去包装一下下.
示例代码
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; /** * 使用Callable示例 */ public class FutureTest { public static void main(String[] args) throws ExecutionException, InterruptedException { FutureTask<Integer> task = new FutureTask<Integer>(new Callable<Integer>() { @Override public Integer call() throws Exception { int total = 0; for (int j = 0; j < 100; j++) { System.out.println("total = "+ total); total += j; } return total; } }); Thread thread = new Thread(task); thread.start(); Integer total = task.get(); System.out.println("求和:" + total); } }
在工作中,我们大多使用线程池对象操作Callable任务,并且获取任务返回值. 其实jdk提供的线程池ThreadPoolExecutor类操作Callable任务也是通过FutureTask类来包装的,
下面是源码
public <T> Future<T> submit(Callable<T> task) { if (task == null) throw new NullPointerException(); RunnableFuture<T> ftask = newTaskFor(task); execute(ftask); return ftask; }
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) { return new FutureTask<T>(callable); }
涨知识了吧....
一下取消任务的正确姿势
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; /** * 使用Callable示例 */ public class FutureTest { public static void main(String[] args) throws ExecutionException, InterruptedException { FutureTask<Integer> task = new FutureTask<Integer>(new Callable<Integer>() { @Override public Integer call() throws Exception { int total = 0; for (int j = 0; j < 100; j++) { if (Thread.currentThread().isInterrupted()) { System.out.println("取消任务..."); return null; } System.out.println("total = " + total); total += j; } return total; } }); Thread thread = new Thread(task); thread.start(); // 便于测试观察,主线程睡1ms Thread.currentThread().sleep(1); // 取消任务 task.cancel(true); } }
task.cancle(true): 该方法并不会真正的取消任务,它只会给任务线程打上一个终断的标识,相当于说,主线程说你可以停了....
Thread.currentThread().isInterrupted() : 任务线程检测自个身上是否有终断标识,如果发现有终断任务的标识, 好吧,我不干了,结束任务....