我们发现上面提到的不管是继承Thread类还是实现Runnable接口,发现有两个问题,第一个是无法抛出更多的异常,第二个是线程执行完毕之后并无法获得线程的返回值。那么下面的这种实现方式就可以完成我们的需求。这种方式的实现就是我们后面要详细介绍的Future模式,只是在jdk5的时候,官方给我们提供了可用的API,我们可以直接使用。但是使用这种方式创建线程比上面两种方式要复杂一些,步骤如下。
创建一个类实现Callable接口,实现call方法。这个接口类似于Runnable接口,但比Runnable接口更加强大,增加了异常和返回值。
创建一个FutureTask,指定Callable对象,做为线程任务。
创建线程,指定线程任务。
启动线程
代码如下:
package com.roocon.thread.t4; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; public class CallableTest { public static void main(String[] args) throws Exception { Callable<Integer> call = new Callable<Integer>() { @Override public Integer call() throws Exception { System.out.println("thread start .. "); Thread.sleep(2000); return 1; } }; FutureTask<Integer> task = new FutureTask<>(call); Thread t = new Thread(task); t.start(); System.out.println("do other thing .. "); System.out.println("拿到线程的执行结果 : " + task.get()); } }
执行结果如下:
do other thing .. thread start .. 拿到线程的执行结果 : 1
Callable中可以通过范型参数来指定线程的返回值类型。通过FutureTask的get方法拿到线程的返回值。