Runnable 是一个接口,里面只声明了一个方法run();返回值为void所以无法拿到执行完的结果。只能通过共享变量或者线程通信来搞定。
//函数式接口注解
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
Callable同样也只是一个接口,只声明了一个方法call(),可以看出来他是一个泛型接口,call方法返回结果类型V。
@FunctionalInterface
public interface Callable {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
Future就是对具体的Runable或者Callable任务的执行结果进行取消,查询是否完成,获取结果。
public interface Future {
//取消任务,成功返回true,失败 返回false, 参数mayInterruptIfRunning表示是否允许取消正在运行的任务,
boolean cancel(boolean mayInterruptIfRunning);
//返回任务是否取消成功
boolean isCancelled();
//返回任务是否完成
boolean isDone();
//返回执行结果,若任务没有执行完,则会阻塞等待执行结果返回
V get() throws InterruptedException, ExecutionException;
//返回执行结果,若在指定时间内没有返回则直接返回null
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
FutureTask实现了RunnableFuture接口,RunableFuture接口继承了Runable和Future接口,所以他既可以被线程执行,也可以作为Future得到Callable的返回值。
public class FutureTask<V> implements RunnableFuture<V>;
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}
Callabel Future实例
//定义一个Callabel实现类
public class CallabeTask implements Callable {
@Override
public Integer call() throws Exception {
System.out.println("调用CallableTask");
Thread.sleep(3000);
System.out.println("辅线程计算完毕");
return 1;
}
}
//测试程序
public class test {
public static void main(String[] args) throws InterruptedException, ExecutionException{
ExecutorService excutor=Executors.newCachedThreadPool();
CallabeTask task=new CallabeTask();
Future result=excutor.submit(task);
excutor.shutdown();
System.out.println("主线程执行");
System.out.println("辅线程结果"+result.get());
}
}
执行结果:调用CallableTask
主线程执行
辅线程计算完毕
辅线程结果1
Callable 和FutureTask
public class test {
public static void main(String[] args) throws InterruptedException, ExecutionException{
ExecutorService excutor=Executors.newCachedThreadPool();
CallabeTask task=new CallabeTask();
FutureTask futureTask=new FutureTask(task);
excutor.submit(futureTask);
excutor.shutdown();
System.out.println("主线程执行");
System.out.println("辅线程结果"+futureTask.get());
}
}
执行结果:
主线程执行
调用CallableTask
辅线程计算完毕
辅线程结果1
CompletableFutures是java8中新增加的一个类,主要用来处理异步。
public class test {
public static void main(String[] args) throws InterruptedException, ExecutionException{
//线程池
ExecutorService excutor=Executors.newFixedThreadPool(5);
//生成CompletableFuture实例,并指定任务执行逻辑
CompletableFuture resultFuture=CompletableFuture.supplyAsync(()->{
System.out.println("completableFuture 1 running");
try {
Thread.sleep(3000);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("completableFuture 1 complete");
return "hello completablefuture";
},excutor);
System.out.println(" main thread complete");
//调用Future的get()方法获取执行结果。
System.out.println(resultFuture.get());
}
}
}
CompletableFuture不但可以调用get()方法获取执行结果,也可以使用回调函数来得到处理结果。
ExecutorService excutor=Executors.newFixedThreadPool(5);
CompletableFuture resultFuture=CompletableFuture.supplyAsync(()->{
System.out.println("completableFuture 1 running");
try {
Thread.sleep(3000);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("completableFuture 1 complete");
return "hello completablefuture";
},excutor);
System.out.println(" main thread complete");
//回调获取执行结果 thenAccept使用同一线程执行任务,并获取结果,thenAcceptAsync使用不同线程
resultFuture.thenAcceptAsync((m)->{
System.out.println(m);
System.out.println("Get Result by Back Function ");
});
}
CompletableFuture可以通过completeExceptionally 函数来发出异常通知,同时我们也可以显示声明异常处理
ExecutorService excutor=Executors.newFixedThreadPool(5);
CompletableFuture resultFuture=CompletableFuture.supplyAsync(()->{
System.out.println("completableFuture 1 running");
try {
Thread.sleep(3000);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("completableFuture 1 complete");
return "hello completablefuture";
},excutor);
System.out.println(" main thread complete");
resultFuture.thenAcceptAsync((m)->{
System.out.println(m);
System.out.println("thenaccept running");
//显示声明异常处理
}).exceptionally((t)->{
System.out.println("异常处理开始");
System.out.println(t.getMessage());
return null;
});
//发出异常通知
resultFuture.completeExceptionally(new Exception("异常"));
System.out.println(resultFuture.get());
thenApply方法可以把多个future组合在一起。
ExecutorService excutor=Executors.newFixedThreadPool(5);
CompletableFuture resultFuture=CompletableFuture.supplyAsync(()->{
System.out.println("resultFuture"+Thread.currentThread().getName());
System.out.println("resultFuture");
return "hello result1";
},excutor);
CompletableFuture<Integer> resultFuture1=resultFuture.thenApplyAsync((t)->{
System.out.println("resultFuture1"+Thread.currentThread().getName());
System.out.println("resultFuture1");
return t.length();
},excutor);
CompletableFuture<Double> resultFuture2=resultFuture1.thenApplyAsync(r->{
System.out.println("resultFuture2"+Thread.currentThread().getName());
return r*2.0;},excutor);
System.out.println(resultFuture2.get());
CompletableFuture还有许多方法,来满足不同的需求场景,具体的方法 还需要使用到的时候在来进行具体分析。
CompletableFuture背后也依靠Fork/join框架(还未深入了解),来实现异步与并发。