一. Future
站在用戶的角度思考問題,與客戶深入溝通,找到東海網(wǎng)站設(shè)計(jì)與東海網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名注冊(cè)、虛擬主機(jī)、企業(yè)郵箱。業(yè)務(wù)覆蓋東海地區(qū)。
JDK 5引入了Future模式。Future接口是Java多線程Future模式的實(shí)現(xiàn),在java.util.concurrent包中,可以來進(jìn)行異步計(jì)算。
Future模式是多線程設(shè)計(jì)常用的一種設(shè)計(jì)模式。Future模式可以理解成:我有一個(gè)任務(wù),提交給了Future,F(xiàn)uture替我完成這個(gè)任務(wù)。期間我自己可以去做任何想做的事情。一段時(shí)間之后,我就便可以從Future那兒取出結(jié)果。
Future的接口很簡單,只有五個(gè)方法。
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; }
Future接口的方法介紹如下:
一般情況下,我們會(huì)結(jié)合Callable和Future一起使用,通過ExecutorService的submit方法執(zhí)行Callable,并返回Future。
ExecutorService executor = Executors.newCachedThreadPool(); Future<String> future = executor.submit(() -> { //Lambda 是一個(gè) callable, 提交后便立即執(zhí)行,這里返回的是 FutureTask 實(shí)例 System.out.println("running task"); Thread.sleep(10000); return "return task"; }); try { Thread.sleep(1000); } catch (InterruptedException e) { } System.out.println("do something else"); //前面的的 Callable 在其他線程中運(yùn)行著,可以做一些其他的事情 try { System.out.println(future.get()); //等待 future 的執(zhí)行結(jié)果,執(zhí)行完畢之后打印出來 } catch (InterruptedException e) { } catch (ExecutionException e) { } finally { executor.shutdown(); }
比起future.get(),其實(shí)更推薦使用get (long timeout, TimeUnit unit) 方法,設(shè)置了超時(shí)時(shí)間可以防止程序無限制的等待future的結(jié)果。
二. CompletableFuture介紹
2.1 Future模式的缺點(diǎn)
Future雖然可以實(shí)現(xiàn)獲取異步執(zhí)行結(jié)果的需求,但是它沒有提供通知的機(jī)制,我們無法得知Future什么時(shí)候完成。
要么使用阻塞,在future.get()的地方等待future返回的結(jié)果,這時(shí)又變成同步操作。要么使用isDone()輪詢地判斷Future是否完成,這樣會(huì)耗費(fèi)CPU的資源。
2.2 CompletableFuture介紹
Netty、Guava分別擴(kuò)展了Java 的 Future 接口,方便異步編程。
Java 8新增的CompletableFuture類正是吸收了所有Google Guava中ListenableFuture和SettableFuture的特征,還提供了其它強(qiáng)大的功能,讓Java擁有了完整的非阻塞編程模型:Future、Promise 和 Callback(在Java8之前,只有無Callback 的Future)。
CompletableFuture能夠?qū)⒒卣{(diào)放到與任務(wù)不同的線程中執(zhí)行,也能將回調(diào)作為繼續(xù)執(zhí)行的同步函數(shù),在與任務(wù)相同的線程中執(zhí)行。它避免了傳統(tǒng)回調(diào)最大的問題,那就是能夠?qū)⒖刂屏鞣蛛x到不同的事件處理器中。
CompletableFuture彌補(bǔ)了Future模式的缺點(diǎn)。在異步的任務(wù)完成后,需要用其結(jié)果繼續(xù)操作時(shí),無需等待??梢灾苯油ㄟ^thenAccept、thenApply、thenCompose等方式將前面異步處理的結(jié)果交給另外一個(gè)異步事件處理線程來處理。
三. CompletableFuture特性
3.1 CompletableFuture的靜態(tài)工廠方法
方法名 | 描述 |
---|---|
runAsync(Runnable runnable) | 使用ForkJoinPool.commonPool()作為它的線程池執(zhí)行異步代碼。 |
runAsync(Runnable runnable, Executor executor) | 使用指定的thread pool執(zhí)行異步代碼。 |
supplyAsync(Supplier<U> supplier) | 使用ForkJoinPool.commonPool()作為它的線程池執(zhí)行異步代碼,異步操作有返回值 |
supplyAsync(Supplier<U> supplier, Executor executor) | 使用指定的thread pool執(zhí)行異步代碼,異步操作有返回值 |
runAsync 和 supplyAsync 方法的區(qū)別是runAsync返回的CompletableFuture是沒有返回值的。
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { System.out.println("Hello"); }); try { future.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println("CompletableFuture");
而supplyAsync返回的CompletableFuture是由返回值的,下面的代碼打印了future的返回值。
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello"); try { System.out.println(future.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println("CompletableFuture");
3.2 Completable
方法名 | 描述 |
---|---|
complete(T t) | 完成異步執(zhí)行,并返回future的結(jié)果 |
completeExceptionally(Throwable ex) | 異步執(zhí)行不正常的結(jié)束 |
future.get()在等待執(zhí)行結(jié)果時(shí),程序會(huì)一直block,如果此時(shí)調(diào)用complete(T t)會(huì)立即執(zhí)行。
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello"); future.complete("World"); try { System.out.println(future.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); }
執(zhí)行結(jié)果:
World
可以看到future調(diào)用complete(T t)會(huì)立即執(zhí)行。但是complete(T t)只能調(diào)用一次,后續(xù)的重復(fù)調(diào)用會(huì)失效。
如果future已經(jīng)執(zhí)行完畢能夠返回結(jié)果,此時(shí)再調(diào)用complete(T t)則會(huì)無效。
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } future.complete("World"); try { System.out.println(future.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); }
執(zhí)行結(jié)果:
Hello
如果使用completeExceptionally(Throwable ex)則拋出一個(gè)異常,而不是一個(gè)成功的結(jié)果。
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello"); future.completeExceptionally(new Exception()); try { System.out.println(future.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); }
執(zhí)行結(jié)果:
java.util.concurrent.ExecutionException: java.lang.Exception
...
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
網(wǎng)站標(biāo)題:Java8新的異步編程方式CompletableFuture實(shí)現(xiàn)
瀏覽地址:http://muchs.cn/article2/gedsic.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)、手機(jī)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)公司、微信小程序、企業(yè)建站、網(wǎng)站收錄
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)