除了通过Runnable注入以及实现Thread类的run方法之外(其实都是Runnable),java还提供了Callable、Future和FutureTask这几个与多线程相关的概念,不过这几个类型都只能用于线程池中。
Callable声明如下:
public interface Callable<V>{
V call() throws Exception;
}
Callable感觉和Runnable非常相似,除了上面说的只能用于线程池,不同点在于Callable是一个泛型接口,允许返回一个泛型对象,同时支持抛出异常。
public class ThreadDemo5 {
public static void main(String[] args) {
MyThread5<A> t1=new MyThread5<A>();
ExecutorService pool=Executors.newSingleThreadExecutor();//创建单一线程池
pool.submit(t1);
}
}
abstract class BaseObject{
String str;
}
class A extends BaseObject{
public A(){
str="This is A.";
}
}
class MyThread5<T extends BaseObject> implements Callable<T>{
@Override
public T call() throws Exception {
System.out.println("MyThread5的call方法执行");
return (T) new A();
}
}
执行之后,你会发现,输出了“MyThread5的call方法执行”,但是,要如何获取返回值呢?
我们发现,sumbit方法返回一个Future类的对象,Future类为线程池提供了一些类任务标准:cancle用于对执行结果的取消;isDone用于判断是否完成;get用于获取callable的返回值,set用于结果设置。所以,当我们需要获取返回值的时候,直接利用get方法即可,注意使用get方法会直接阻塞线程,直到获取到对应的结果:
main函数改写为:public static void main(String[] args) {
MyThread5<A> t1=new MyThread5<A>();
ExecutorService pool=Executors.newSingleThreadExecutor();//创建单一线程池
Future future=pool.submit(t1);
try {
BaseObject a=(BaseObject)future.get();
System.out.println("str="+a.str);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
结果输出:
MyThread5的call方法执行
str=This is A.
事实上,Future只是一个抽象接口(public abstract interfacejava.util.concurrent.Future),真正实现的类是FutureTask<T>。FutureTask的声明为
public class java.util.concurrent.FutureTask implements java.util.concurrent.RunnableFuture
,可以看出实现了RunnableFuture接口,而RunnableFuture又继承了Runnable 、Future接口
public abstract interface java.util.concurrent.RunnableFuture extends java.lang.Runnable,java.util.concurrent.Future
故拥有它们两者的特点,因此,FutureTask既可以和Runnable一样,通过Thread封装执行,也可以交给线程池来执行。
public class ThreadDemo6 {
public static void main(String[] args) {
FutureTask<String> ft=new FutureTask<String>(new Callable(){
@Override
public Object call() throws Exception {
return "FutureTask 返回值";
}
});
ExecutorService pool=Executors.newSingleThreadExecutor();
pool.submit(ft);
try {
System.out.println(ft.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
执行结果:
FutureTask 返回值