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

futuretask用法及使用場(chǎng)景介紹

 更新時(shí)間:2017年10月11日 15:30:31   作者:linchunquan  
這篇文章主要介紹了futuretask用法及使用場(chǎng)景介紹,小編覺(jué)得挺不錯(cuò)的,這里分享給大家,供大家參考。

FutureTask可用于異步獲取執(zhí)行結(jié)果或取消執(zhí)行任務(wù)的場(chǎng)景。通過(guò)傳入Runnable或者Callable的任務(wù)給FutureTask,直接調(diào)用其run方法或者放入線程池執(zhí)行,之后可以在外部通過(guò)FutureTask的get方法異步獲取執(zhí)行結(jié)果,因此,F(xiàn)utureTask非常適合用于耗時(shí)的計(jì)算,主線程可以在完成自己的任務(wù)后,再去獲取結(jié)果。另外,F(xiàn)utureTask還可以確保即使調(diào)用了多次run方法,它都只會(huì)執(zhí)行一次Runnable或者Callable任務(wù),或者通過(guò)cancel取消FutureTask的執(zhí)行等。

1. FutureTask執(zhí)行多任務(wù)計(jì)算的使用場(chǎng)景

利用FutureTask和ExecutorService,可以用多線程的方式提交計(jì)算任務(wù),主線程繼續(xù)執(zhí)行其他任務(wù),當(dāng)主線程需要子線程的計(jì)算結(jié)果時(shí),在異步獲取子線程的執(zhí)行結(jié)果。

package futuretask; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.concurrent.Callable; 
import java.util.concurrent.ExecutionException; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.FutureTask; 
public class FutureTaskForMultiCompute { 
  public static void main(String[] args) { 
    FutureTaskForMultiCompute inst=new FutureTaskForMultiCompute(); 
    // 創(chuàng)建任務(wù)集合 
    List<FutureTask<Integer>> taskList = new ArrayList<FutureTask<Integer>>(); 
    // 創(chuàng)建線程池 
    ExecutorService exec = Executors.newFixedThreadPool(5); 
    for (int i = 0; i < 10; i++) { 
      // 傳入Callable對(duì)象創(chuàng)建FutureTask對(duì)象 
      FutureTask<Integer> ft = new FutureTask<Integer>(inst.new ComputeTask(i, ""+i)); 
      taskList.add(ft); 
      // 提交給線程池執(zhí)行任務(wù),也可以通過(guò)exec.invokeAll(taskList)一次性提交所有任務(wù); 
      exec.submit(ft); 
    } 
    System.out.println("所有計(jì)算任務(wù)提交完畢, 主線程接著干其他事情!"); 
    // 開(kāi)始統(tǒng)計(jì)各計(jì)算線程計(jì)算結(jié)果 
    Integer totalResult = 0; 
    for (FutureTask<Integer> ft : taskList) { 
      try { 
        //FutureTask的get方法會(huì)自動(dòng)阻塞,直到獲取計(jì)算結(jié)果為止 
        totalResult = totalResult + ft.get(); 
      } catch (InterruptedException e) { 
        e.printStackTrace(); 
      } catch (ExecutionException e) { 
        e.printStackTrace(); 
      } 
    } 
    // 關(guān)閉線程池 
    exec.shutdown(); 
    System.out.println("多任務(wù)計(jì)算后的總結(jié)果是:" + totalResult); 
  } 
  private class ComputeTask implements Callable<Integer> { 
    private Integer result = 0; 
    private String taskName = ""; 
    public ComputeTask(Integer iniResult, String taskName){ 
      result = iniResult; 
      this.taskName = taskName; 
      System.out.println("生成子線程計(jì)算任務(wù): "+taskName); 
    } 
    public String getTaskName(){ 
      return this.taskName; 
    } 
    @Override 
    public Integer call() throws Exception { 
      // TODO Auto-generated method stub 
      for (int i = 0; i < 100; i++) { 
        result =+ i; 
      } 
      // 休眠5秒鐘,觀察主線程行為,預(yù)期的結(jié)果是主線程會(huì)繼續(xù)執(zhí)行,到要取得FutureTask的結(jié)果是等待直至完成。 
      Thread.sleep(5000); 
      System.out.println("子線程計(jì)算任務(wù): "+taskName+" 執(zhí)行完成!"); 
      return result; 
    } 
  } 
} 

2. FutureTask在高并發(fā)環(huán)境下確保任務(wù)只執(zhí)行一次

在很多高并發(fā)的環(huán)境下,往往我們只需要某些任務(wù)只執(zhí)行一次。這種使用情景FutureTask的特性恰能勝任。舉一個(gè)例子,假設(shè)有一個(gè)帶key的連接池,當(dāng)key存在時(shí),即直接返回key對(duì)應(yīng)的對(duì)象;當(dāng)key不存在時(shí),則創(chuàng)建連接。對(duì)于這樣的應(yīng)用場(chǎng)景,通常采用的方法為使用一個(gè)Map對(duì)象來(lái)存儲(chǔ)key和連接池對(duì)應(yīng)的對(duì)應(yīng)關(guān)系,典型的代碼如下面所示:

private Map<String, Connection> connectionPool = new HashMap<String, Connection>(); 
private ReentrantLock lock = new ReentrantLock(); 
public Connection getConnection(String key){ 
  try{ 
    lock.lock(); 
    if(connectionPool.containsKey(key)){ 
      return connectionPool.get(key); 
    } 
    else{ 
      //創(chuàng)建 Connection 
      Connection conn = createConnection(); 
      connectionPool.put(key, conn); 
      return conn; 
    } 
  } 
  finally{ 
    lock.unlock(); 
  } 
} 
//創(chuàng)建Connection 
private Connection createConnection(){ 
  return null; 
} 

在上面的例子中,我們通過(guò)加鎖確保高并發(fā)環(huán)境下的線程安全,也確保了connection只創(chuàng)建一次,然而確犧牲了性能。改用ConcurrentHash的情況下,幾乎可以避免加鎖的操作,性能大大提高,但是在高并發(fā)的情況下有可能出現(xiàn)Connection被創(chuàng)建多次的現(xiàn)象。這時(shí)最需要解決的問(wèn)題就是當(dāng)key不存在時(shí),創(chuàng)建Connection的動(dòng)作能放在connectionPool之后執(zhí)行,這正是FutureTask發(fā)揮作用的時(shí)機(jī),基于ConcurrentHashMap和FutureTask的改造代碼如下:

private ConcurrentHashMap<String,FutureTask<Connection>>connectionPool = new ConcurrentHashMap<String, FutureTask<Connection>>(); 
public Connection getConnection(String key) throws Exception{ 
  FutureTask<Connection>connectionTask=connectionPool.get(key); 
  if(connectionTask!=null){ 
    return connectionTask.get(); 
  } 
  else{ 
    Callable<Connection> callable = new Callable<Connection>(){ 
      @Override 
      public Connection call() throws Exception { 
        // TODO Auto-generated method stub 
        return createConnection(); 
      } 
    }; 
    FutureTask<Connection>newTask = new FutureTask<Connection>(callable); 
    connectionTask = connectionPool.putIfAbsent(key, newTask); 
    if(connectionTask==null){ 
      connectionTask = newTask; 
      connectionTask.run(); 
    } 
    return connectionTask.get(); 
  } 
} 
//創(chuàng)建Connection 
private Connection createConnection(){ 
  return null; 
} 

經(jīng)過(guò)這樣的改造,可以避免由于并發(fā)帶來(lái)的多次創(chuàng)建連接及鎖的出現(xiàn)。

總結(jié)

以上就是本文關(guān)于futuretask用法及使用場(chǎng)景介紹的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以參閱:淺談Java多線程處理中Future的妙用(附源碼)、Java利用future及時(shí)獲取多線程運(yùn)行結(jié)果Java多線程ForkJoinPool實(shí)例詳解等,有什么問(wèn)題可以隨時(shí)留言,歡迎各位參閱本站其他相關(guān)專題。

相關(guān)文章

  • Java實(shí)現(xiàn)簡(jiǎn)單堆棧代碼

    Java實(shí)現(xiàn)簡(jiǎn)單堆棧代碼

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)單堆棧代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • java中http請(qǐng)求之restTemplate配置超時(shí)時(shí)間問(wèn)題解決

    java中http請(qǐng)求之restTemplate配置超時(shí)時(shí)間問(wèn)題解決

    這篇文章主要介紹了java中http請(qǐng)求之restTemplate配置超時(shí)時(shí)間,本文給大家分享三種解決方法,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • 實(shí)例解析如何正確使用Java數(shù)組

    實(shí)例解析如何正確使用Java數(shù)組

    同一種類型數(shù)據(jù)的集合。其實(shí)數(shù)組就是一個(gè)容器。運(yùn)算的時(shí)候有很多數(shù)據(jù)參與運(yùn)算,那么首先需要做的是什么下面我們就一起來(lái)看看。
    2016-07-07
  • 詳解Java的線程的優(yōu)先級(jí)以及死鎖

    詳解Java的線程的優(yōu)先級(jí)以及死鎖

    這篇文章主要介紹了詳解Java的線程的優(yōu)先級(jí)以及死鎖,線程是Java編程學(xué)習(xí)中的重要知識(shí),需要的朋友可以參考下
    2015-09-09
  • springboot2+es7使用RestHighLevelClient的示例代碼

    springboot2+es7使用RestHighLevelClient的示例代碼

    本文主要介紹了springboot2+es7使用RestHighLevelClient的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • SpringCloud gateway如何修改返回?cái)?shù)據(jù)

    SpringCloud gateway如何修改返回?cái)?shù)據(jù)

    這篇文章主要介紹了SpringCloud gateway如何修改返回?cái)?shù)據(jù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Spring5使用JSR 330標(biāo)準(zhǔn)注解的方法

    Spring5使用JSR 330標(biāo)準(zhǔn)注解的方法

    從Spring3.0之后,除了Spring自帶的注解,我們也可以使用JSR330的標(biāo)準(zhǔn)注解,本文主要介紹了Spring5使用JSR 330標(biāo)準(zhǔn)注解,感興趣的可以了解一下
    2021-09-09
  • RxJava中多種場(chǎng)景的實(shí)現(xiàn)總結(jié)

    RxJava中多種場(chǎng)景的實(shí)現(xiàn)總結(jié)

    這篇文章給大家詳細(xì)介紹了RxJava中多種場(chǎng)景的實(shí)現(xiàn),對(duì)大家學(xué)習(xí)使用RxJava具有一定的參考借鑒價(jià)值,有需要的朋友們可以參考學(xué)習(xí),下面來(lái)一起看看吧。
    2016-10-10
  • 淺談在Java中使用Callable、Future進(jìn)行并行編程

    淺談在Java中使用Callable、Future進(jìn)行并行編程

    這篇文章主要介紹了淺談在Java中使用Callable、Future進(jìn)行并行編程,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Java對(duì)象Serializable接口實(shí)現(xiàn)詳解

    Java對(duì)象Serializable接口實(shí)現(xiàn)詳解

    這篇文章主要介紹了Java對(duì)象Serializable接口實(shí)現(xiàn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12

最新評(píng)論

临泉县| 鄂伦春自治旗| 如东县| 津南区| 子长县| 西林县| 噶尔县| 苏尼特右旗| 岑溪市| 安康市| 万载县| 基隆市| 怀仁县| 莱西市| 米易县| 达拉特旗| 新营市| 旬阳县| 乐安县| 定南县| 长葛市| 乾安县| 新泰市| 舞阳县| 瓦房店市| 南陵县| 富川| 盐城市| 黑山县| 游戏| 共和县| 红安县| 南安市| 大竹县| 集安市| 桃源县| 卓资县| 西华县| 和田市| 明水县| 如皋市|