经过实现Callable接口一样可以建立一个线程,但与Runnable接口不一样的是Callable接口有返回值。java
JDK源码:并发
@FunctionalInterface public interface Callable<V> { V call() throws Exception; }
能够看出,与Runnable一样属于一个接口方法,但二者不一样的是,Callable接口有返回值且支持泛型。ide
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方法。线程
JDK源码:code
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 做为底层任务的结果。对象
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可以在⾼并发环境下确保任务只执⾏⼀次。get