Callable,Future与FutureTask
作用
通过实现Callable接口同样能够创建一个线程,但与Runnable接口不同的是Callable接口有返回值。
Callable接口
JDK源码:
@FunctionalInterface
public interface Callable<V> {
V call() throws Exception;
}
可以看出,与Runnable同样属于一个接口方法,但两者不同的是,Callable接口有返回值且支持泛型。
使用
Callable的使用一般是配置线程池ExecutorService来使用。其可以通过一个submit()方法来让一个Callable接口执行,返回一个Future。通过Future的get方法可以获得结果。
案例:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Demo03 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 创建一个线程池
ExecutorService es=Executors.newCachedThreadPool();
// 创建线程对象
MyThread mt=new MyThread();
//使用Future
Future<Integer> fu=es.submit(mt);
//通过get方法获得返回值
System.out.println(fu.get());
}
}
class MyThread implements Callable<Integer>{
@Override
public Integer call() throws Exception {
// TODO Auto-generated method stub
Thread.sleep(1000);
return 2;
}
}
get方法调用后会阻塞当前线程,实际使用时建议重写get方法,使用可以设置超时时间的重载get方法。
Future接口
JDK源码:
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
其中cancel方法是试图取消一个线程的执行。
cancel并不一定能取消线程的执行,因为一个任务可能已完成,已取消或者一些其它原因,存在取消失败的可能。
返回值boolean,当取消成功返回true,失败返回false。
参数mayInterruptIfRunning,表示是否使用中断的方式取消线程执行。
所以有时候,为了让任务有能够取消的功能,就使⽤ Callable 来代替 Runnable 。
如果为了可取消性⽽使⽤ Future 但⼜不提供可⽤的结果,则可以声明 Future<?> 形式类型、并返回 null 作为底层任务的结果。
FutureTask类
JDK源码:
public interface RunnableFuture<V> extends Runnable, Future<V>
FutureTask实现了RunnableFuture接口,而RunnableFuture接口则继承了Runnable接口与Future接口。
FutureTask类相当于是一个工具类,使用它我们不用自己去实现Future接口中那些复杂的抽象方法。
案例:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class Demo04 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 创建线程池
ExecutorService es=Executors.newCachedThreadPool();
//创建FutureTask类
FutureTask<Integer> ft=new FutureTask<>(new Task());
//使用sumit方法
es.submit(ft);
//输出
System.out.println(ft.get());
}
}
class Task implements Callable<Integer>{
@Override
public Integer call() throws Exception {
// TODO Auto-generated method stub
Thread.sleep(1000);
return 3;
}
}
在很多⾼并发的环境下,有可能Callable和FutureTask会创建多次。FutureTask能够在⾼并发环境下确保任务只执⾏⼀次。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。