Callable,Future与FutureTask

作用

通过实现Callable接口同样可能创立一个线程,但与Runnable接口不同的是Callable接口有返回值。

Callable接口

JDK源码

@FunctionalInterfacepublic 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可能在⾼并发环境下确保工作只执⾏⼀次。