Callable接口类似于Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。
但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。
如果想在线程执行完毕之后获取一个结果,那么Callable接口是一个选择
与Runnable不同,这个接口开始于JDK5
泛型类型
通过API观察这个接口可以发现,该接口后带了一个泛型
这个泛型指定的是返回值的类型
方法
1
| V call() throws Exception
|
由于版本靠后,Thread类没有关于它的构造方法.
但是ExecutorService的submit方法有这个类型
以下是简单的案例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public static void main(String[] args) { ExecutorService pool = Executors.newFixedThreadPool(2); Future<Integer>[] futures = new Future[2]; for (int i = 0;i < 2;i++) futures[i] = pool.submit(new MyCallable((i+1)*100)); for (int i = 0;i<futures.length;i++) { try { Integer result = futures[i].get(); System.out.println(result); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } } class MyCallable implements Callable<Integer>{ private int number; public MyCallable(){} public MyCallable(int number){this.number = number;} @Override public Integer call() throws Exception { int sum = 0; for (int i = 1;i <= number;i++){ sum += i; } return sum; } }
|
由于返回的结果是Future接口类型,详情参见下一节
执行结果如下,可以看出得到了返回值

Future接口
方法
1 2 3 4 5 6 7 8
| boolean cancel(boolean mayInterruptIfRunning) V get()throws InterruptedException, ExecutionException V get(long timeout,TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException boolean isCancelled() boolean isDone()
|
简单的测试案例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public static void main(String[] args) { ExecutorService pool = Executors.newFixedThreadPool(2); Futur9e<Integer> future = pool.submit(new MyCallable(10));
System.out.println(future.isCancelled()); System.out.println(future.isDone());
} class MyCallable implements Callable<Integer>{ private int number; public MyCallable(){} public MyCallable(int number){this.number = number;} @Override public Integer call() throws Exception { int sum = 0; for (int i = 1;i <= number;i++){ sum += i; Thread.sleep(100); } return sum; } }
|
首先是直接测试两个判断,返回的都是false
由于未取消任务,第一个false;由于main执行到isDone线程未执行结束,第二个false;
以下是执行结果 :

打开指定1000ms以内获取执行结果,此时若完成了任务,isDone为true
我这里得到了结果,执行结果如下 :

设置超时时间变小,会得到超时的异常。但是异常不属于取消任务,第一个仍为false
我这里设置的是995ms,其实有个问题,那就是执行应该使用1000ms 为什么到995才异常
但是异常结束也算是完成,第二个为true
执行结果如下 :

最后将cancel方法打开,不管设置true还是false;get方法都会异常
都会抛出CancellationException撤销异常
执行结果如下 :
