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

簡析Java中的util.concurrent.Future接口

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

在一個單線程應(yīng)用中,當(dāng)你調(diào)用一個方法只有計算結(jié)束才會返回結(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() 看上去是無害的, 但是它需要任意長的時間來完成。同時,為了減少延遲,在等待結(jié)果的期間,你可能需要同時獨(dú)立的處理其它的工作。以前你可能會啟動一個新的線程 或者等待結(jié)果(共享內(nèi)存,鎖,糟糕的 wait()/notify()對).

通過 Future<T> 模式,它會變得明朗:
 

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();

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

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


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

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

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


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

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


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


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

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ùn)行的計算包裝到可調(diào)用的<String>,并submit()到線程池,這個線程池包含10個線程。 提交后返回Future<String>的實現(xiàn),就像以某種方式鏈接到你的任務(wù)和線程池。明顯的你的任務(wù)不會被立即執(zhí)行,相反它被放到一個隊列中,稍后會被線程拉出來, 現(xiàn)在需要搞清楚cancel()的兩個特別的意義是什么——你可以取消在隊列中停留的任務(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é)果到AsyncResult來實現(xiàn)Future,但是這個方法本身不會與線程池交互或者異步處理。稍后 Spring會代理所有的調(diào)用來startDownloading()并在線程池中執(zhí)行。 在EJB中,相同的特性通過加@Asynchronousannotation 來完成。

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Spring中一個少見的引介增強(qiáng)IntroductionAdvisor

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

最新評論

宜城市| 扶余县| 文山县| 离岛区| 沅江市| 马公市| 健康| 扎赉特旗| 靖州| 双柏县| 左贡县| 阿克陶县| 崇阳县| 高邮市| 呼图壁县| 台湾省| 环江| 无极县| 柘城县| 舒城县| 永嘉县| 涪陵区| 黑龙江省| 舒城县| 搜索| 汤原县| 小金县| 达拉特旗| 抚宁县| 潼南县| 吉隆县| 德化县| 颍上县| 乾安县| 文登市| 楚雄市| 龙江县| 林芝县| 克拉玛依市| 共和县| 静乐县|