日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

java.util.concurrent.Future基础

發(fā)布時(shí)間:2023/12/3 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java.util.concurrent.Future基础 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在此,我開(kāi)始撰寫(xiě)一系列有關(guān)編程語(yǔ)言中的未來(lái)概念(也稱(chēng)為promise或delays )的文章,標(biāo)題為: Back to the Future 。 由于對(duì)異步,事件驅(qū)動(dòng),并行和可伸縮系統(tǒng)的需求不斷增長(zhǎng),所以期貨是非常重要的抽象,如今比以往任何時(shí)候都更加重要。 在第一篇文章中,我們將發(fā)現(xiàn)最基本的java.util.concurrent.Future<T>接口。 稍后,我們將跳入其他框架,庫(kù)甚至語(yǔ)言。 Future<T>是相當(dāng)有限的,但必須了解,ekhm,將來(lái)部分。

在單線程應(yīng)用程序中,當(dāng)您調(diào)用方法時(shí),它僅在計(jì)算完成IOUtils.toString()返回( IOUtils.toString()來(lái)自Apache Commons IO ):

public String downloadContents(URL url) throws IOException {try(InputStream input = url.openStream()) {return IOUtils.toString(input, StandardCharsets.UTF_8);} }//...final String contents = downloadContents(new URL("http://www.example.com"));

downloadContents()看起來(lái)是無(wú)害的1 ,但它甚至可能需要花費(fèi)很長(zhǎng)時(shí)間才能完成。 此外,為了減少延遲,您可能希望在等待結(jié)果的同時(shí)進(jìn)行其他獨(dú)立的處理。 在過(guò)去,您將啟動(dòng)一個(gè)新Thread并以某種方式等待結(jié)果(共享內(nèi)存,鎖,可怕的wait() / notify()對(duì)等),使用Future<T>會(huì)更加愉快:

public static Future<String> startDownloading(URL url) {//... }final Future<String> contentsFuture = startDownloading(new URL("http://www.example.com")); //other computation final String contents = contentsFuture.get();

我們將很快實(shí)現(xiàn)startDownloading() 。 目前,重要的是要了解這些原理。 startDownloading() 不阻塞,等待外部網(wǎng)站。 相反,它會(huì)立即返回,并返回輕量級(jí)的Future<String>對(duì)象。 此對(duì)象保證 String將來(lái)會(huì)可用。 不知道什么時(shí)候,但是保留此引用,一旦存在,您就可以使用Future.get()檢索它。 換句話說(shuō), Future是一個(gè)尚未存在的對(duì)象的代理或包裝。 異步計(jì)算完成后,您可以提取它。 那么Future提供了什么API?

Future.get()是最重要的方法。 它阻塞并等待,直到承諾的結(jié)果可用(已解決 )。 因此,如果我們確實(shí)需要該String ,則只需調(diào)用get()并等待。 有一個(gè)過(guò)載的版本可以接受超時(shí),所以一旦出現(xiàn)問(wèn)題,您將不會(huì)永遠(yuǎn)等待。 如果等待時(shí)間太長(zhǎng),則會(huì)拋出TimeoutException 。

在某些用例中,您可能希望窺視“ Future ,如果結(jié)果尚不可用,請(qǐng)繼續(xù)。 使用isDone()可以做到這一點(diǎn)。 想象一下這樣一種情況,您的用戶(hù)正在等待一些異步計(jì)算,而您想讓他知道我們?nèi)栽诘却⑼瑫r(shí)進(jìn)行一些計(jì)算:

final Future<String> contentsFuture = startDownloading(new URL("http://www.example.com")); while (!contentsFuture.isDone()) {askUserToWait();doSomeComputationInTheMeantime(); }

到最后調(diào)用contentsFuture.get()是保證立即返回,而不是因?yàn)閴KFuture.isDone()返回true 。 如果遵循上述模式,請(qǐng)確保您不忙于等待,每秒每秒調(diào)用isDone()數(shù)百萬(wàn)次。

取消期貨是我們尚未討論的最后一個(gè)方面。 想象一下,您開(kāi)始了一些異步作業(yè),并且您只能在給定的時(shí)間內(nèi)等待它。 如果2秒鐘后仍沒(méi)有出現(xiàn),我們會(huì)放棄并傳播錯(cuò)誤或解決它。 但是,如果您是一個(gè)好公民,您應(yīng)該以某種方式告訴這個(gè)未來(lái)的目標(biāo):我不再需要您,那就算了。 通過(guò)不運(yùn)行過(guò)時(shí)的任務(wù)來(lái)節(jié)省處理資源。 語(yǔ)法很簡(jiǎn)單:

contentsFuture.cancel(true); //meh...

我們都喜歡神秘的布爾參數(shù),不是嗎? 取消有兩種口味。 通過(guò)將false傳遞給mayInterruptIfRunning參數(shù),當(dāng)Future表示尚未開(kāi)始的計(jì)算結(jié)果時(shí),我們僅取消尚未開(kāi)始的任務(wù)。 但是,如果我們的Callable.call()已經(jīng)在中間,則讓它結(jié)束。 但是,如果我們傳遞true ,則Future.cancel()將更具攻擊性,并嘗試中斷已經(jīng)在運(yùn)行的作業(yè)。 怎么樣? 考慮所有引發(fā)臭名昭著的InterruptedException方法,即Thread.sleep() , Object.wait() , Condition.await()以及許多其他方法(包括Future.get() )。 如果您禁止使用任何此類(lèi)方法,而某人決定取消您的Callable ,則它們實(shí)際上將拋出InterruptedException ,表示有人試圖中斷當(dāng)前正在運(yùn)行的任務(wù)。

因此,我們現(xiàn)在了解什么是Future<T> –將來(lái)會(huì)得到的東西的占位符。 這就像尚未生產(chǎn)的汽車(chē)的鑰匙。 但是,實(shí)際上如何在應(yīng)用程序中獲取Future<T>的實(shí)例? 兩種最常見(jiàn)的來(lái)源是線程池和異步方法(由您的線程池支持)。 因此,我們的startDownloading()方法可以重寫(xiě)為:

private final ExecutorService pool = Executors.newFixedThreadPool(10);public Future<String> startDownloading(final URL url) throws IOException {return pool.submit(new Callable<String>() {@Overridepublic String call() throws Exception {try (InputStream input = url.openStream()) {return IOUtils.toString(input, StandardCharsets.UTF_8);}}}); }

語(yǔ)法很多,但基本思想很簡(jiǎn)單:將長(zhǎng)時(shí)間運(yùn)行的計(jì)算包裝在Callable<String>然后submit()它們submit()到10個(gè)線程的線程池中。 提交返回Future<String>某些實(shí)現(xiàn),最有可能以某種方式鏈接到您的任務(wù)和線程池。 顯然,您的任務(wù)不會(huì)立即執(zhí)行。 而是將其放置在隊(duì)列中,該隊(duì)列稍后(甚至可能更晚)由池中的線程輪詢(xún)。 現(xiàn)在應(yīng)該清楚這兩種cancel()含義–您始終可以取消仍然駐留在該隊(duì)列中的任務(wù)。 但是取消已經(jīng)運(yùn)行的任務(wù)要復(fù)雜一些。

可以遇到Future另一個(gè)地方是Spring和EJB。 例如,在Spring框架中,您可以使用@Async注釋您的方法 :

@Async public Future<String> startDownloading(final URL url) throws IOException {try (InputStream input = url.openStream()) {return new AsyncResult<>(IOUtils.toString(input, StandardCharsets.UTF_8));} }

注意,我們只是將結(jié)果包裝在實(shí)現(xiàn)Future AsyncResult 。 但是該方法本身不處理線程池或異步處理。 Spring稍后將代理所有對(duì)startDownloading()調(diào)用,并在線程池中運(yùn)行它們。 EJB中的@Asynchronous批注提供了完全相同的功能。

因此,我們了解了很多有關(guān)java.util.concurrent.Future 。 現(xiàn)在該承認(rèn)了–該界面非常有限,尤其是與其他語(yǔ)言相比時(shí)。 以后再說(shuō)。

1 –您不熟悉Java 7的try-with-resources功能嗎? 您現(xiàn)在最好切換到Java 7。 Java 6將在兩周內(nèi)不再維護(hù)。

參考: NoBlogDefFound博客上來(lái)自我們的JCG合作伙伴 Tomasz Nurkiewicz的java.util.concurrent.Future基礎(chǔ) 。

翻譯自: https://www.javacodegeeks.com/2013/02/java-util-concurrent-future-basics.html

總結(jié)

以上是生活随笔為你收集整理的java.util.concurrent.Future基础的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。