无锡哪里有做网站,微信公众号平台建立,网站建设放在什么科目,wordpress位置CompletableFuture#xff08;可完成的Future#xff09; 一个可完成的Future#xff0c;在我们调用他的get方法的时候#xff0c;他会阻塞等待这个任务完成来获取他的结果。 当然也可以为这个任务注册一些回调#xff0c;类似于完成时#xff0c;出现异常时#xff0c;…CompletableFuture可完成的Future 一个可完成的Future在我们调用他的get方法的时候他会阻塞等待这个任务完成来获取他的结果。 当然也可以为这个任务注册一些回调类似于完成时出现异常时或者执行超时等额外处理。 使用
CompletableFuture.suppleAsync 异步执行一个任务并返回结果 CompletableFuture.runAsync 异步执行一个任务不返回结果 这两方法都可以为我们快速的创建一个CompletableFuture对象
CompletableFutureString completableFuture CompletableFuture.supplyAsync(() - {System.out.println(Thread.currentThread().getName() :supplyAsync start);return supplyAsync;
});CompletableFutureString completableFuture CompletableFuture.runAsync(() - {System.out.println(Thread.currentThread().getName() :runAsync start);return runAsync;
});这两个方法都是可以有第二个参数的也就是可以执行线程池这里默认是**Fork-Join-Pool**(一个可以将一个大任务很自然的分解为多个子任务的线程池)。 回调有哪些
方法参数描述thenApplyT - U对结果进行处理并返回一个新的结果thenAccpetT - void对结果进行处理返回结果为VoidthenComposeT - CompletableFuture对结果调用这个函数来进行处理并返回一个新的结果handle(T,Throwable) - U与thenApply类似但是他可以处理异常根据异常对象是否为null可以判断是否出现异常。不报错也会执行whenCompletable(T,Throwable) - void类似handle 但是不返回结果不报错也会执行exceptionallyThrowable - U出现异常时返回一个结果报错时才会执行。completableOnTimeoutT, long, TimeUnit如果超时返回一个指定的结果。超时后的链式操作都不执行orTimeoutlong, TimeUnit超时返回一个异常 TimeOutException超时后的链式操作都不执行thenRunRunable执行Runable,返回void对于不需要任务的返回结果
示例
private static final ThreadPoolExecutor THREAD_POOL_EXECUTOR new ThreadPoolExecutor(10, 10, 1, TimeUnit.MINUTES, new ArrayBlockingQueue(50));public static void main(String[] args) {CompletableFutureString completableFuture CompletableFuture.supplyAsync(() - {System.out.println(Thread.currentThread().getName() :supplyAsync);return supplyAsync;});completableFuture.thenApply((result) - {System.out.println(Thread.currentThread().getName() :thenApply1 );return result \nthenApply1;}).thenAccept((result) - {System.out.println(Thread.currentThread().getName() :thenAccept );}).thenCompose(result -CompletableFuture.supplyAsync(() - {try {System.out.println(Thread.currentThread().getName() :thenCompose );TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {throw new RuntimeException(e);}return result \nthenCompose;}))// thenCompose 超时了orTimeout 之前的的操作都将被忽略 之后的还会执行.thenAccept((result) - {System.out.println(Thread.currentThread().getName() :ignore );})// .completeOnTimeout(completeOnTimeout, 1, TimeUnit.SECONDS)// 这里会抛出一个TimeOutException.orTimeout(1, TimeUnit.SECONDS)// throwable则可以获取到 TimeOutException .handleAsync((result, throwable) - {System.out.println(Thread.currentThread().getName() :handleAsync );if (throwable null) {return result;}throwable.printStackTrace();return result \nhandleAsync;}, THREAD_POOL_EXECUTOR)// 因为TimeOutException 被handleAsync处理了所以这里也没有异常了throwable为null.whenComplete((result, throwable) - {System.out.println(Thread.currentThread().getName() :whenComplete );if (throwable null) {return;}throwable.printStackTrace();}).thenRun(() - {System.out.println(Thread.currentThread().getName() :thenRun );});try {Thread.sleep(5000); // 添加短暂的延迟 因为是异步任务这里不等待一下的话main线程就终止了} catch (InterruptedException e) {e.printStackTrace();}THREAD_POOL_EXECUTOR.shutdownNow();
}#### 执行结果
ForkJoinPool.commonPool-worker-3:supplyAsync
ForkJoinPool.commonPool-worker-3:thenApply1
ForkJoinPool.commonPool-worker-3:thenAccept
ForkJoinPool.commonPool-worker-3:thenCompose
pool-1-thread-1:handleAsync
pool-1-thread-1:whenComplete
pool-1-thread-1:thenRun
java.util.concurrent.TimeoutException注意回调时机即可。 Async回调 我们这里使用一个叫handleAsync的方法与普通的handle相比他是执行的线程发送了变化。 使用Async在大多数情况下都会是在一个新的线程下去帮我们执行这个回调而普通的则是在原有由原有执行任务的线程去执行这个回调。 这里的大多数情况是指我们在使用自定义线程池的时候。而我们的Fork-Join-Pool可能会为一些短暂的任务重用相同的线程以减少线程的创建和销毁开销。 get、join 当我们的CompletableFuture提供了返回值的时候我们可以通过get或者join方法来阻塞的得到这个结果 与之不同是get他可能会抛出异常而join不会。通常我们使用join 组合CompletableFuture 可以根据某种条件去执行两个或者多个CompletableFuture 因为组合太多这里就简单描述下我自己比较常用的 方法参数描述static allOfCompletableFuture?…所以任务都执行完成后完成返回结果为voidstatic anyOfCompletableFuture?…任意任务都执行完成后完成返回结果为void
示例
public static void main(String[] args) {// 1.两个任务都执行完成后才完成CompletableFuture.allOf(CompletableFuture.runAsync(()-{System.out.println(supplyAsync1);}),CompletableFuture.runAsync(()-{// 异步任务等待1秒try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(supplyAsync2);}));// 任意一个完成则完成CompletableFuture.anyOf(CompletableFuture.runAsync(()-{System.out.println(supplyAsync3);}),CompletableFuture.runAsync(()-{// 异步任务等待2秒try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(supplyAsync4);}));// 主线程只等待一秒 try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {throw new RuntimeException(e);}
}### 结果
supplyAsync1
supplyAsync3
supplyAsync2allOf 因为需要两个都完成所以等待一秒后完成输出supplyAsync1、supplyAsync2 antOf 任意一个完成则算结束。因为第二个等待两秒主线程已经结束了main已经退出了所以只输出supplyAsync3