最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

簡(jiǎn)析Java中的util.concurrent.Future接口

 更新時(shí)間:2015年07月10日 12:07:56   投稿:goldensun  
這篇文章主要介紹了簡(jiǎn)析Java中的util.concurrent.Future接口,作者把future歸結(jié)為在未來(lái)得到目標(biāo)對(duì)象的占位符,需要的朋友可以參考下

在一個(gè)單線程應(yīng)用中,當(dāng)你調(diào)用一個(gè)方法只有計(jì)算結(jié)束才會(huì)返回結(jié)果( IOUtils.toString()  comes from Apache Commons IO ):
 

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

downloadContents() 看上去是無(wú)害的, 但是它需要任意長(zhǎng)的時(shí)間來(lái)完成。同時(shí),為了減少延遲,在等待結(jié)果的期間,你可能需要同時(shí)獨(dú)立的處理其它的工作。以前你可能會(huì)啟動(dòng)一個(gè)新的線程 或者等待結(jié)果(共享內(nèi)存,鎖,糟糕的 wait()/notify()對(duì)).

通過(guò) 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();

我們馬上會(huì)實(shí)現(xiàn) startDownloading(), startDownloading()不會(huì)被阻塞,而是等待外部的站點(diǎn)回應(yīng),你理解這一原則是很重要的。 相反,如果它快速返回了,返回一個(gè)輕量級(jí)的Future<String> 對(duì)象。 這個(gè)對(duì)象是一個(gè)promise那么將來(lái)字符串類型就是可用的,雖然我們不知道什么時(shí)候,但是會(huì)保留這個(gè)引用直到它返有結(jié)果返回,你就可以通過(guò)Future.get()來(lái)獲取它。 換句話說(shuō),F(xiàn)uture是一個(gè)代理或者一個(gè)對(duì)象的包裝,不是真實(shí)的目標(biāo)對(duì)象。一旦異步計(jì)算完成,你就可以提取它。 那么Future提供了什么樣的接口呢?

Future.get()是最重要的方法。它阻塞和等待直到承諾的結(jié)果是可用狀態(tài), 因此如果我們確實(shí)需要這個(gè)字符串,就調(diào)用get() 方法然后等待。 還有一個(gè)接受超時(shí)參數(shù)的重載版本,如果哪里出現(xiàn)問(wèn)題你就不用一直等待下去,超過(guò)設(shè)定時(shí)間就會(huì)拋出 TimeoutException。


在某些情況下,你可能想不停地偷偷看看Future是否可用了。這可以通過(guò)isDone()來(lái)完成。想象一個(gè)情景,你的用戶等待某些異步的計(jì)算,你想讓他知道這種情況, 同時(shí)去做一些其它的計(jì)算:
 

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

最后Future.get()調(diào)用的內(nèi)容會(huì)保證馬上返回,不會(huì)被阻塞,因?yàn)镕uture.isDone() 返回了true。如果你遵循這個(gè)模式,就不會(huì)忙于每秒百萬(wàn)次的交替等待和調(diào)用isDone()。


取消futrues是最后一個(gè)我們還沒(méi)有覆蓋到的。想象你啟動(dòng)了異步的工作并且你只能等待一些時(shí)間, 如果2秒鐘后,我們放棄,或者把錯(cuò)誤傳遞出去,或者采用臨時(shí)方案解決它。然而,你是一個(gè)好市民,你應(yīng)該告訴這個(gè)future對(duì)象:我不需要你了,你別管了。 那么你可以通過(guò)停止過(guò)時(shí)的任務(wù),來(lái)節(jié)約資源。語(yǔ)法很簡(jiǎn)單:
 

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


我們都喜歡隱藏的,布爾類型的參數(shù),對(duì)嗎?取消可以通過(guò)兩種方式來(lái)實(shí)現(xiàn):在任務(wù)啟動(dòng)前通過(guò)傳遞false參數(shù)來(lái)取消,前提是當(dāng)Future表達(dá)的結(jié)果計(jì)算開(kāi)始之前。一旦Callable.call()已經(jīng)運(yùn)行到一半,那么我們想讓它結(jié)束,如果我們傳遞true,那么Future.call()就會(huì)具有侵入性,試圖打斷正在運(yùn)行的工作。你覺(jué)得這樣好嗎?現(xiàn)象那些拋出InterruptedException這個(gè)聲名狼藉的異常的方法,如Thread.sleep(), Object.wait(),Condition.await(),等,甚至包括Future.get(). 如果你被阻塞在這種方法并且有人決定取消你的調(diào)用,他們會(huì)毫無(wú)疑問(wèn)的拋出InterruptionException,并發(fā)出有人要打斷當(dāng)前運(yùn)行的任務(wù)。


因此我們現(xiàn)在明白了Future是什么--- 一個(gè)占位符,你可以在未來(lái)得到目標(biāo)對(duì)象。就像對(duì)于一輛車,還沒(méi)有制造出來(lái)的鑰匙。但是你怎樣才能在應(yīng)用程序中獲得Future的實(shí)例? 兩種最普通的資源是線程池和異步方法(線程池支持)。因此, startDownloading()方法可以被重寫(xiě)為:
 

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


雖然有大量的繁瑣的語(yǔ)法問(wèn)題,但是基本思想是簡(jiǎn)單的: 把需要長(zhǎng)時(shí)間運(yùn)行的計(jì)算包裝到可調(diào)用的<String>,并submit()到線程池,這個(gè)線程池包含10個(gè)線程。 提交后返回Future<String>的實(shí)現(xiàn),就像以某種方式鏈接到你的任務(wù)和線程池。明顯的你的任務(wù)不會(huì)被立即執(zhí)行,相反它被放到一個(gè)隊(duì)列中,稍后會(huì)被線程拉出來(lái), 現(xiàn)在需要搞清楚cancel()的兩個(gè)特別的意義是什么——你可以取消在隊(duì)列中停留的任務(wù),也可以取消早已運(yùn)行的任務(wù),但這是一件比較復(fù)雜的事情。


你還可以在Spring 和 EJB 碰上Future。比如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ǎn)單地通過(guò)包裝結(jié)果到AsyncResult來(lái)實(shí)現(xiàn)Future,但是這個(gè)方法本身不會(huì)與線程池交互或者異步處理。稍后 Spring會(huì)代理所有的調(diào)用來(lái)startDownloading()并在線程池中執(zhí)行。 在EJB中,相同的特性通過(guò)加@Asynchronousannotation 來(lái)完成。

相關(guān)文章

  • 關(guān)于JavaEE匿名內(nèi)部類和Lambda表達(dá)式的注意事項(xiàng)

    關(guān)于JavaEE匿名內(nèi)部類和Lambda表達(dá)式的注意事項(xiàng)

    這篇文章主要介紹了關(guān)于JavaEE匿名內(nèi)部類和Lambda表達(dá)式的注意事項(xiàng),匿名內(nèi)部類顧名思義是沒(méi)有修飾符甚至沒(méi)有名稱的內(nèi)部類,使用匿名內(nèi)部類需要注意哪些地方,我們一起來(lái)看看吧
    2023-03-03
  • Java面試題及答案集錦(基礎(chǔ)題122道,代碼題19道)

    Java面試題及答案集錦(基礎(chǔ)題122道,代碼題19道)

    本文是小編收集整理的關(guān)于java基礎(chǔ)面試題及答案集錦,基礎(chǔ)題目有122道,代碼題目有19道,非常不錯(cuò),值得收藏,需要的朋友參考下
    2017-01-01
  • springboot zuul實(shí)現(xiàn)網(wǎng)關(guān)的代碼

    springboot zuul實(shí)現(xiàn)網(wǎng)關(guān)的代碼

    這篇文章主要介紹了springboot zuul實(shí)現(xiàn)網(wǎng)關(guān)的代碼,在為服務(wù)架構(gòu)體系里,網(wǎng)關(guān)是非常重要的環(huán)節(jié),他實(shí)現(xiàn)了很多功能,具體哪些功能大家跟隨小編一起通過(guò)本文學(xué)習(xí)吧
    2018-10-10
  • Java使用HttpClient實(shí)現(xiàn)文件下載

    Java使用HttpClient實(shí)現(xiàn)文件下載

    這篇文章主要為大家詳細(xì)介紹了Java使用HttpClient實(shí)現(xiàn)文件下載,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • java實(shí)現(xiàn)猜字母游戲

    java實(shí)現(xiàn)猜字母游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)猜字母小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • Java從ftp服務(wù)器上傳與下載文件的實(shí)現(xiàn)

    Java從ftp服務(wù)器上傳與下載文件的實(shí)現(xiàn)

    這篇文章主要給大家介紹了關(guān)于Java從ftp服務(wù)器上傳與下載文件的實(shí)現(xiàn)方法,最近項(xiàng)目中需要實(shí)現(xiàn)將文件先存放到ftp上,需要的時(shí)候再?gòu)膄tp上下載,做的過(guò)程中碰到了問(wèn)題,所以這里總結(jié)下,需要的朋友可以參考下
    2023-08-08
  • httpclient模擬post請(qǐng)求json封裝表單數(shù)據(jù)的實(shí)現(xiàn)方法

    httpclient模擬post請(qǐng)求json封裝表單數(shù)據(jù)的實(shí)現(xiàn)方法

    下面小編就為大家?guī)?lái)一篇httpclient模擬post請(qǐng)求json封裝表單數(shù)據(jù)的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-12-12
  • mybatis的mapper.xml中resultMap標(biāo)簽的使用詳解

    mybatis的mapper.xml中resultMap標(biāo)簽的使用詳解

    這篇文章主要介紹了mybatis的mapper.xml中resultMap標(biāo)簽的使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • 教你如何用Eclipse創(chuàng)建一個(gè)Maven項(xiàng)目

    教你如何用Eclipse創(chuàng)建一個(gè)Maven項(xiàng)目

    這篇文章主要介紹了教你如何用Eclipse創(chuàng)建一個(gè)Maven項(xiàng)目,文中有非常詳細(xì)的代碼示例,對(duì)正在入門Java的小伙伴們是非常有幫助的喲,需要的朋友可以參考下
    2021-05-05
  • Spring中一個(gè)少見(jiàn)的引介增強(qiáng)IntroductionAdvisor

    Spring中一個(gè)少見(jiàn)的引介增強(qiáng)IntroductionAdvisor

    這篇文章主要為大家介紹了Spring中一個(gè)少見(jiàn)的引介增強(qiáng)IntroductionAdvisor實(shí)戰(zhàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08

最新評(píng)論

手游| 沁水县| 修文县| 丰镇市| 剑川县| 达孜县| 涞源县| 香河县| 武夷山市| 石林| 石林| 松阳县| 惠安县| 方城县| 古交市| 江达县| 江永县| 离岛区| 山阳县| 上饶市| 四平市| 怀宁县| 沙湾县| 莱阳市| 荃湾区| 芷江| 罗定市| 安多县| 星座| 连城县| 闽清县| 桂平市| 衡阳市| 长丰县| 司法| 平利县| 贞丰县| 乌鲁木齐县| 仪陇县| 濮阳市| 漠河县|