国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Java8中新增新特性異步編程之CompletableFuture

開發(fā) 前端
Future是從JDK1.5開始有的,目的是獲取異步任務(wù)執(zhí)行的結(jié)果,通常情況會結(jié)合ExecutorService及Callable一起使用。

環(huán)境:Java8

在Java 8中, 新增加了一個CompletableFuture類,該類提供了差不多50個左右的方法(都是用來完成各種異步場景需求),并且結(jié)合了Future的優(yōu)點(繼承自Future類),提供了比Future更為強大的功能,這使得在異步編程方面變的簡單,同時還提供了函數(shù)式編程的能力,可以通過回調(diào)的方式處理計算結(jié)果,并且提供了轉(zhuǎn)換和組合CompletableFuture的各種方法。

Future基本應(yīng)用

Future是從JDK1.5開始有的,目的是獲取異步任務(wù)執(zhí)行的結(jié)果,通常情況會結(jié)合ExecutorService及Callable一起使用。

1. Future結(jié)合Callable使用

單任務(wù)執(zhí)行

private static class Task implements Callable<String> {


  @Override
  public String call() throws Exception {
    TimeUnit.SECONDS.sleep(3) ;
    return "success";
  }
    
}
public static void main(String[] args) throws Exception {
  ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 3, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10)) ;
  Future<String> future = executor.submit(new Task()) ;
  String result = future.get() ;
  System.out.println("執(zhí)行結(jié)果:" + result) ;
}

當(dāng)執(zhí)行到future.get()方法的時候會阻塞,等待3s后繼續(xù)執(zhí)行。

多個任務(wù)同時執(zhí)行

private static class Task implements Callable<String> {
  private int sleep ;
  public Task(int sleep) {
    this.sleep = sleep ;
  }
    
  @Override
  public String call() throws Exception {
    TimeUnit.SECONDS.sleep(this.sleep) ;
    return "success";
  }
}
public static void main(String[] args) throws Exception {
  ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 3, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10)) ;
  Future<String> future1 = executor.submit(new Task(3)) ;
  Future<String> future2 = executor.submit(new Task(2)) ;
  Future<String> future3 = executor.submit(new Task(1)) ;
  String result1 = future1.get() ;
  String result2 = future2.get() ;
  String result3 = future3.get() ;
  System.out.println("result1:" + result1 + "\t" + "result2:" + result2 + "\t" + "result3:" + result3) ;
}

以上代碼執(zhí)行的3個任務(wù)分別用時3,2,1s。future1用時最長。

從運行的結(jié)果看到即便future2, future3執(zhí)行時間短也必須等待future1執(zhí)行完后才會繼續(xù),雖然你可以倒過來獲取結(jié)果,但是在實際項目中的應(yīng)用你應(yīng)該是不能確認每個任務(wù)執(zhí)行需要多長時間,誰先執(zhí)行完就先獲取誰。

雖然這種同步阻塞的方式在有些場景下還是很有必要的。但由于它的同步阻塞導(dǎo)致了當(dāng)前線程不能干其它的事必須一致等待。

CompletionService解決Future的缺點

CompletionService是一邊生產(chǎn)新的任務(wù),一邊處理已經(jīng)完成的任務(wù)。簡單地說就是CompletionService不管任務(wù)執(zhí)行先后順序,誰先執(zhí)行完就處理誰。

private static class Task implements Callable<String> {
  private int time;
  private String name ;
  public Task(int time, String name) {
    this.time = time ;
    this.name = name ;
  }
  @Override
  public String call() throws Exception {
    TimeUnit.SECONDS.sleep(this.time) ;
    return name ;
  }
    
}
public static void main(String[] args) throws Exception {
  ThreadPoolExecutor pool = new ThreadPoolExecutor(3, 3, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10)) ;
  CompletionService<String> cs = new ExecutorCompletionService<>(pool) ;
  cs.submit(new Task(3, "name" + 3)) ;
  cs.submit(new Task(1, "name" + 1)) ;
  cs.submit(new Task(2, "name" + 2)) ;
  for (int i = 0; i < 3; i++) {
    System.out.println(cs.take().get()) ;
  }
}

通過執(zhí)行結(jié)果發(fā)現(xiàn),任務(wù)的結(jié)果獲取是以誰先執(zhí)行完處理誰與任務(wù)的執(zhí)行先后沒有關(guān)系。

CompletableFuture異步編程

CompletableFuture通過如下4個靜態(tài)方法來執(zhí)行異步任務(wù)

圖片圖片

2. 簡單異步任務(wù)鏈式調(diào)用執(zhí)行

ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 5, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10)) ;
CompletableFuture.runAsync(() -> {
  try {
    TimeUnit.SECONDS.sleep(3) ;
    System.out.println(Thread.currentThread().getName() + ", 1 任務(wù)執(zhí)行完成") ;
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
}, executor).thenRun(() -> {
  try {
    TimeUnit.SECONDS.sleep(2) ;
    System.out.println(Thread.currentThread().getName() + ", 2 任務(wù)執(zhí)行完成") ;
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
}) ;
System.out.println("主線程:" + Thread.currentThread().getName()) ;
executor.shutdown() ;

執(zhí)行結(jié)果:

圖片圖片

3. 獲取上一步任務(wù)執(zhí)行結(jié)果及任務(wù)完成處理

CompletableFuture.supplyAsync(() -> {
  try {
    TimeUnit.SECONDS.sleep(3) ;
    System.out.println(Thread.currentThread().getName() + ", 1 任務(wù)執(zhí)行完成") ;
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  return "1" ;
}, executor).thenApply(res -> {
  System.out.println("獲取到上一步任務(wù)執(zhí)行結(jié)果:" + res) ;
  try {
    TimeUnit.SECONDS.sleep(2) ;
    System.out.println(Thread.currentThread().getName() + ", 2 任務(wù)執(zhí)行完成") ;
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  return "2" ;
}).whenComplete((res, tx) -> {
  System.out.println("獲取到結(jié)果:" + res) ;
  if (tx != null) {
    System.err.println("發(fā)生錯誤了:" + tx.getMessage()) ;
  }
  executor.shutdown();
}) ;
System.out.println("主線程:" + Thread.currentThread().getName()) ;

執(zhí)行結(jié)果:

圖片圖片

這里如果任務(wù)執(zhí)行的時候發(fā)生了異常那么在whenComplete方法中的res 會為空,tx為發(fā)生異常的對象。沒有異常時res有執(zhí)行的機構(gòu),tx異常對象為空。

4. 異步任務(wù)異常處理

CompletableFuture.supplyAsync(() -> {
  try {
    TimeUnit.SECONDS.sleep(3) ;
    System.out.println(Thread.currentThread().getName() + ", 1 任務(wù)執(zhí)行完成") ;
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  return "1" ;
}, executor).thenApply(res -> {
  System.out.println("獲取到上一步任務(wù)執(zhí)行結(jié)果:" + res) ;
  try {
    TimeUnit.SECONDS.sleep(2) ;
    System.out.println(Thread.currentThread().getName() + ", 2 任務(wù)執(zhí)行完成") ;
    System.out.println(1 / 0) ;
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  return "2" ;
}).exceptionally(tx -> {
  System.out.println(Thread.currentThread().getName() + ", 任務(wù)執(zhí)行發(fā)生了異常") ;
  return "error" ;
}).whenComplete((res, tx) -> {
  System.out.println("獲取到結(jié)果:" + res) ;
  if (tx != null) {
    System.err.println("發(fā)生錯誤了:" + tx.getMessage()) ;
  }
  executor.shutdown();
}) ;
System.out.println("主線程:" + Thread.currentThread().getName()) ;

這里我們?nèi)藶榈闹圃飚惓?1 / 0 。

執(zhí)行結(jié)果:

圖片圖片

根據(jù)執(zhí)行結(jié)果當(dāng)發(fā)生異常時進入exceptionally方法,最終進入whenComplete方法此時 tx異常對象是發(fā)生異常的異常對象。

5. 所有任務(wù)完成才算完成任務(wù)

CompletableFuture.allOf

CompletableFuture<Double> calc1 = CompletableFuture.supplyAsync(() -> {
  try {
    TimeUnit.SECONDS.sleep(2) ;
    System.out.println(Thread.currentThread().getName() + ", calc1任務(wù)執(zhí)行完成") ;
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  return 10D ;
}, executor) ;
    
CompletableFuture<Double> calc2 = CompletableFuture.supplyAsync(() -> {
  try {
    TimeUnit.SECONDS.sleep(5) ;
    System.out.println(Thread.currentThread().getName() + ", calc2任務(wù)執(zhí)行完成") ;
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  return 20D ;
}, executor) ;
// 當(dāng)任何一個任務(wù)發(fā)生異常,這里的tx都不會為null
CompletableFuture.allOf(calc1, calc2).whenComplete((res, tx) -> {
  System.out.println("獲取到結(jié)果:" + res + ", " + tx) ;
  try {
    System.out.println(calc1.get()) ;
    System.out.println(calc2.get()) ;
  } catch (InterruptedException e) {
    e.printStackTrace();
  } catch (ExecutionException e) {
    e.printStackTrace();
  }
  executor.shutdown();
}) ;

執(zhí)行結(jié)果:

圖片

在這里whenComplete中的res是沒有結(jié)果的,要獲取數(shù)據(jù)我們的分別調(diào)用get方法獲取。

6. handle方法對結(jié)果處理

CompletableFuture.supplyAsync(() -> {
  try {
    TimeUnit.SECONDS.sleep(2) ;
    System.out.println(Thread.currentThread().getName() + ", 1 任務(wù)執(zhí)行完成") ;
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  return "0" ;
}, executor).handle((res, tx) -> {
  // 處理結(jié)果數(shù)據(jù)
  return res + "1" ;
}).whenComplete((res, tx) -> {
  System.out.println("獲取到結(jié)果:" + res) ;
  if (tx != null) {
    System.err.println("發(fā)生錯誤了:" + tx.getMessage()) ;
  }
  executor.shutdown();
}) ;

執(zhí)行結(jié)果:

正確

圖片圖片

發(fā)生異常時:

圖片圖片

當(dāng)發(fā)生異常時handle方法中的res是沒有值的,tx異常對象為發(fā)生異常的異常對象。

7. 合并異步任務(wù)

將兩個異步任務(wù)完成后合并處理

CompletableFuture.thenCombine

CompletableFuture<Double> task1 = CompletableFuture.supplyAsync(() -> {
  try {
    TimeUnit.SECONDS.sleep(2) ;
    System.out.println(Thread.currentThread().getName() + ", 任務(wù)1執(zhí)行完成") ;
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  return 10d ;
}, executor) ;
CompletableFuture<Double> task2 = CompletableFuture.supplyAsync(() -> {
  try {
    TimeUnit.SECONDS.sleep(2) ;
    System.out.println(Thread.currentThread().getName() + ", 任務(wù)2執(zhí)行完成") ;
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  return 20d ;
}, executor) ;
task1.thenCombine(task2, (t1, t2) -> {
  System.out.println(Thread.currentThread().getName() + ", 合并任務(wù)完成") ;
  return t1 + "," + t2 ;
}).whenComplete((res, tx) -> {
  System.out.println("獲取到結(jié)果:" + res) ;
  if (tx != null) {
    System.err.println("發(fā)生錯誤了:" + tx.getMessage()) ;
  }
  executor.shutdown();
}) ;

執(zhí)行結(jié)果:

圖片圖片

8. 異步任務(wù)誰快誰就進入下一步的執(zhí)行

CompletableFuture.applyToEither

兩個異步任務(wù)誰先執(zhí)行完誰就繼續(xù)執(zhí)行后續(xù)的操作。

CompletableFuture<Double> task1 = CompletableFuture.supplyAsync(() -> {
  try {
    TimeUnit.SECONDS.sleep(2) ;
    System.out.println(Thread.currentThread().getName() + ", 任務(wù)1執(zhí)行完成") ;
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  return 10d ;
}, executor) ;
CompletableFuture<Double> task2 = CompletableFuture.supplyAsync(() -> {
  try {
    TimeUnit.SECONDS.sleep(2) ;
    System.out.println(Thread.currentThread().getName() + ", 任務(wù)2執(zhí)行完成") ;
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  return 20d ;
}, executor) ;
task1.applyToEither(task2, res -> {
  return res ;
}).whenComplete((res, tx) -> {
  System.out.println("獲取到結(jié)果:" + res) ;
  if (tx != null) {
    System.err.println("發(fā)生錯誤了:" + tx.getMessage()) ;
  }
  executor.shutdown();
}) ;

執(zhí)行結(jié)果:

圖片圖片

9. 兩個異步任務(wù)都執(zhí)行完了才繼續(xù)執(zhí)行

只有兩個任務(wù)都執(zhí)行完成了后才會繼續(xù)。

CompletableFuture.runAfterBoth

CompletableFuture<Double> task1 = CompletableFuture.supplyAsync(() -> {
  try {
    TimeUnit.SECONDS.sleep(2) ;
    System.out.println(Thread.currentThread().getName() + ", 任務(wù)1執(zhí)行完成") ;
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  return 10d ;
}, executor) ;
CompletableFuture<Double> task2 = CompletableFuture.supplyAsync(() -> {
  try {
    TimeUnit.SECONDS.sleep(2) ;
    System.out.println(Thread.currentThread().getName() + ", 任務(wù)2執(zhí)行完成") ;
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  return 20d ;
}, executor) ;
task1.runAfterBoth(task2, () -> {
  System.out.println("任務(wù)都執(zhí)行完成了...") ;
}).whenComplete((res, tx) -> {
  System.out.println("獲取到結(jié)果:" + res) ;
  if (tx != null) {
    System.err.println("發(fā)生錯誤了:" + tx.getMessage()) ;
  }
  executor.shutdown();
}) ;

執(zhí)行結(jié)果:

圖片圖片

10. 等待所有任務(wù)執(zhí)行完成

CompletableFuture.anyOf

CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> {
  sleep(1000) ;
  System.out.println("我是任務(wù)1") ;
  return "Task1" ;
}, executor) ;


CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> {
  sleep(3000) ;
  System.out.println("我是任務(wù)2") ;
  System.out.println(1 / 0) ;
  return "Task2" ;
}, executor) ;
// 任意一個任務(wù)執(zhí)行完成就算完成
// 當(dāng)任務(wù)執(zhí)行發(fā)生異常后,th才不會為null
CompletableFuture.anyOf(task1, task2).whenCompleteAsync((v, th) -> {
  System.out.println("v = " + v) ;
  System.out.println("th = " + th) ;
}, executor) ;

執(zhí)行結(jié)果:

圖片圖片

11. 接收上一個任務(wù)的執(zhí)行結(jié)果

CompletableFuture.supplyAsync(() -> {
  sleep(2000) ;
  System.out.println("第一個任務(wù)執(zhí)行完成...") ;
  // System.out.println(1 / 0) ;
  return new Random().nextInt(10000) ;
}, executor).thenAcceptAsync(res -> { // 接收上一個任務(wù)的執(zhí)行結(jié)果
  System.out.println("任務(wù)執(zhí)行結(jié)果:" + res) ;
}, executor) ;

執(zhí)行結(jié)果:

圖片 圖片

責(zé)任編輯:武曉燕 來源: 實戰(zhàn)案例錦集
相關(guān)推薦

2020-05-29 07:20:00

Java8異步編程源碼解讀

2024-04-18 08:20:27

Java 8編程工具

2022-05-31 07:32:19

JDK8API工具

2021-02-21 14:35:29

Java 8異步編程

2013-08-06 13:58:27

2021-06-06 16:56:49

異步編程Completable

2017-12-21 15:48:11

JavaCompletable

2022-07-08 14:14:04

并發(fā)編程異步編程

2021-03-02 09:34:41

Nodejs14前端代碼

2021-03-04 08:14:37

Java8開發(fā)接口

2021-03-02 07:13:54

Java8版本升級

2022-05-25 07:22:07

ES12JavaScript語言

2021-02-22 11:51:15

Java開發(fā)代碼

2024-10-09 08:42:03

2025-02-06 16:51:30

2024-08-06 09:43:54

Java 8工具編程

2014-07-15 14:48:26

Java8

2022-12-09 07:48:10

Java8Stream表達式

2022-12-30 09:24:23

Java8Stream操作

2023-04-13 07:33:31

Java 8編程工具
點贊
收藏

51CTO技術(shù)棧公眾號

欧美日韩精品欧美日韩精品 | 免费看成人哺乳视频网站| 正在播放亚洲一区| 国产精品久久久久白浆| 色综合天天综合给合国产| 免费在线视频一级不卡| 亚洲欧美在线x视频| 国产露出视频在线观看| 日韩欧美aaa| 中国日本在线视频中文字幕| 天堂av中文在线观看| 国产午夜久久久久| 国产精品片aa在线观看| 精品久久久久久中文字幕一区奶水| 99久久伊人| 蜜桃传媒一区二区| 亚洲日本视频| 一区二区三区日韩视频| 自拍av一区二区三区| 182在线播放| 五月天亚洲综合小说网| 91在线免费网站| 欧美日本在线视频中文字字幕| 亚洲男人的天堂av| 综合天堂av久久久久久久| 亚洲免费一级视频| 国产一区喷水| 中文字幕日本精品| 久久99国产精品尤物| 宅男在线精品国产免费观看| 97精品久久| 久久深夜福利免费观看| 欧美6一10sex性hd| 亚洲精品电影网| 国产第一页在线| 精品国产精品网麻豆系列| gogogogo高清视频在线| 久久久久久91| 国产乱码精品一品二品| 粉嫩一区二区三区国产精品| 亚洲欧美日韩图片| 欧美www视频在线观看| 国产亚洲欧美另类一区二区三区| 性欧美长视频| 僵尸再翻生在线观看| 亚洲精品一区二区三区四区高清| 亚洲精品一区二区三区香蕉| 怡红院亚洲色图| 亚洲观看高清完整版在线观看| a级网站在线观看| 欧美日本免费| 亚洲最大成人网色| 哺乳挤奶一区二区三区免费看 | 一区二区三区| 亚洲欧美日韩视频二区| 一本久久综合亚洲鲁鲁五月天| 国产精品免费一区二区三区在线观看| 日本中文字幕电影在线观看| 欧美激情偷拍自拍| 亚洲一区制服诱惑| 国产调教视频一区| 91久久精品国产91久久性色tv| 日本在线观看天堂男亚洲| 日本在线观看大片免费视频| 亚洲国产精品久久久久秋霞影院 | 欧美三级伦理在线| 亚洲一区二区美女| 午夜精品福利一区二区三区av| 日韩精品一区二区三区电影| 欧美激情综合网| 激情开心成人网| 精品91一区二区三区| 在线精品国产成人综合| 91小视频免费观看| 99精品在线| 亚洲最大成人| 在线黄色av| 日韩一级视频免费观看在线| 国产精品视频入口| 欧美乱大交xxxxx| 91黄色小网站| 日韩免费视频线观看| 性久久久久久| 林ゆな中文字幕一区二区| 91破解版在线看| 国风产精品一区二区| 欧美日韩爱爱视频| 亚洲福利在线看| 亚洲成人自拍网| 91资源在线观看| 91欧美大片| 欧美色蜜桃97| 国产精品美女免费| 欧美日本一区二区| 国产亚洲美州欧州综合国| 中文精品视频| 亚洲成人二区| 好吊色欧美一区二区三区视频| 国产亚洲aⅴaaaaaa毛片| 国产精品国产三级国产普通话99| 99c视频在线| 日本免费黄色小视频| 欧美一区二区三区激情视频| mm1313亚洲国产精品无码试看| 久久久久成人精品| 亚洲精品av在线| 7777精品伊人久久久大香线蕉 | 免费欧美一级视频| 免费视频爱爱太爽了| 视频一区视频二区视频| 国产精品18久久久久久麻辣| 小视频免费在线观看| 99热在线成人| 欧美成人手机在线| 欧美国产视频在线| 国产成人免费视| 国产成人av电影在线观看| 蜜桃在线一区二区三区| 国内精品伊人久久久久av一坑 | 国产av人人夜夜澡人人爽麻豆| 日本在线播放不卡| 在线观看中文字幕不卡| 九色porny自拍| 国产一二三视频| 国产精品pans私拍| 婷婷激情综合| 99香蕉国产精品偷在线观看| 日本欧美一区二区三区| 国产成人综合在线观看| 国产日韩欧美精品在线| 午夜精品成人在线视频| 日韩av网站导航| 亚洲瘦老头同性70tv| 日本怡春院一区二区| 99精彩视频在线观看免费| 欧美怡红院视频| 五月激情六月综合| 亚洲综合成人网| 在线免费观看不卡av| 亚洲精品一区二区三区福利| 色综合久久久888| 四虎永久国产精品| 成人福利视频在| 日日夜夜精品一区| 精品中文在线| 国产乱子精品一区二区在线观看| 欧美1区2区3区4区| 欧美日本精品| 香蕉视频在线免费看| julia中文字幕久久亚洲蜜臀| 在线免费观看的av| 日韩在线观看| 成人小视频在线观看| 色综合一区二区三区| 欧美国产日韩在线| 日韩国产美国| 午夜cr在线观看高清在线视频完整版| 亚洲天堂一区二区| 午夜在线免费视频| 亚洲激情自拍图| 婷婷色播视频| 亚洲国产一区二区精品视频 | 免费看av成人| 白浆在线视频| www国产精品com| 午夜视频在线观看网站| 国产精品久久久久久av下载红粉 | segui88久久综合9999| 国内精品视频在线观看 | 欧美日韩123区| 老司机午夜精品| 欧美va亚洲va香蕉在线| 超碰97在线资源| 天堂在线中文字幕| 成人自拍爱视频| 亚洲在线视频免费观看| 91精品入口蜜桃| 国产成人免费av电影| 国产日产久久高清欧美一区| 成年免费网站| 国产一区不卡| 在线亚洲免费视频| 三区精品视频观看| 成人日韩精品| 免费不卡av| av片在线看| 9999在线视频| 免费在线黄色网址| 在线免费视频你懂得| 欧美激情亚洲天堂| 国产精品亚洲一区二区三区| 亚洲第一在线综合网站| 久久综合九色综合久久久精品综合 | 一区二区三区在线观看视频| 91深夜福利视频| 亚洲一区国产精品| 亚洲精品久久久久| 91午夜国产| 日本亚洲欧美三级| 日本电影一区二区三区|