一、概述
使用Callable
接口创建线程能够返回数据。与Runnable
接口创建线程的方式有点类似,也是需要通过Thread
类来创建线程。由于Thread类的构造函数中没有Callable
接口,选用了FutureTask
类来作为连接创建线程。
FutureTask
类实现了RunnableFuture
接口,而RunnableFuture
接口继承了Runnable, Future
接口。在FutureTask
类中构造函数可以传入Callable
对象,以此建立关系。
通过FutureTask
中的get()
方法来获取Callable
接口中的call()
方法的返回值。
二、步骤:
1.创建一个类实现Callable
接口,实现call()
方法。(在FutureTask
类中的run()
方法实际上就是调用了call()
方法 )
返回值可以任意设置。也可以在指定返回值,如:class MyCallable implements Callable<Integer>
如:
class MyCallable implements Callable {@Overridepublic Object call() throws Exception {return null;}
}
2.创建一个FutureTask
对象,传入Callable
对象。
如:
FutureTask task = new FutureTask(new MyCallable());
3.创建一个线程Thread
,传入FutureTask
对象。然后调用run()
方法,运行该线程。
如:
Thread thread = new Thread(task);
thread.start();
4.获取call()
方法的返回值,通过FutureTask
对象调用get()
方法。
此外: 因为FutureTask
类实现了Runable
接口,那么也可以通过线程池来创建线程
如:
ExecutorService service = new ThreadPoolExecutor(5,5,5, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(10),new ThreadPoolExecutor.DiscardOldestPolicy());
service.submit(task);
三、案例
创建一个线程,call()方法返回1-10000的和。
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class Test {public static void main(String[] args) throws ExecutionException, InterruptedException {FutureTask task = new FutureTask(new MyCallable());Thread thread = new Thread(task);thread.start();System.out.println(task.get());}}
class MyCallable implements Callable<Integer> {@Overridepublic Integer call() throws Exception {System.out.println(Thread.currentThread().getName()+",正在执行!");int sum = 0;for(int i = 0 ; i <10000 ; i++){sum+=i;}return sum;}
}
运行结果