能異步毫不同步,能並行毫不串行java
1. Future緩存
一個Future表明一個異步計算的結果。Future提供檢查計算是否完成、等待計算完成並獲取計算結果的方法。只有當計算完成之後,纔可使用get方法檢索結果,不然將會阻塞直到計算完成。經過調研cancel方法能夠取消執行。另外,還提供了檢查任務是正常完成仍是被取消的方法。一旦計算完成,這個計算不能被取消。異步
簡單用法:ide
1 public class App {
2 ExecutorService executorService = Executors.newFixedThreadPool(3);
3 ArchiveSearcher searcher = new ArchiveSearcher();
4
5 void showSearch(final String target) throws InterruptedException {
6 Future<String> future = executorService.submit(new Callable<String>() {
7 public String call() {
8 return searcher.search(target);
9 }
10 });
11
12 displayOtherThings(); // do other things while searching
13
14 try {
15 displayText(future.get()); // use future
16 } catch (ExecutionException ex) {
17 cleanup();
18 return;
19 }
20 }
21 }
FutureTask類是Future的實現,它同時也實現了Runnable,所以也能夠被Executor執行。例如,上面的代碼能夠被改寫成以下:spa
1 FutureTask<String> future = new FutureTask<String>(new Callable<String>() {
2 public String call() {
3 return searcher.search(target);
4 }
5 });
6 executor.execute(future);
2. FutureTask 對象
一個FutureTask能夠用來包裝一個Callable或Runnable對象。由於FutureTask實現了Runnable接口,一個FutureTask能夠被提交給一個Executor來執行。 blog
3. 示例接口
1 package com.cjs.example;
2
3 import java.util.concurrent.*;
4
5 /**
6 * @author ChengJianSheng
7 * @date 2019-05-22
8 */
9 public class App {
10
11 public static void main(String[] args) throws Exception {
12
13 long t1 = System.currentTimeMillis();
14
15 ExecutorService executorService = Executors.newFixedThreadPool(3);
16
17 FutureTask<String> heatUpWaterFuture = new FutureTask<String>(new Callable<String>() {
18 @Override
19 public String call() throws Exception {
20 System.out.println("燒開水...");
21 Thread.sleep(3000);
22 return "ok";
23 }
24 });
25
26
27 FutureTask<String> cookMealsFuture = new FutureTask<String>(new Callable<String>() {
28 @Override
29 public String call() throws Exception {
30 System.out.println("煮飯...");
31 Thread.sleep(5000);
32 return "ok";
33 }
34 });
35
36 executorService.submit(heatUpWaterFuture);
37 executorService.submit(cookMealsFuture);
38
39 System.out.println("炒菜...");
40
41 Thread.sleep(2000);
42
43 System.out.println("菜炒好了了");
44
45 if (heatUpWaterFuture.get(5000, TimeUnit.SECONDS) == "ok"
46 && cookMealsFuture.get(5000, TimeUnit.SECONDS) == "ok") {
47 System.out.println("開飯了...");
48 }
49
50 long t2 = System.currentTimeMillis();
51 System.out.println("作飯用時:" + (t2-t1) + "ms");
52
53 }
54 }
輸出開發
1 燒開水...
2 煮飯...
3 炒菜...
4 菜炒好了了
5 開飯了...
6 作飯用時:5014ms
在實際開發過程當中,將那些耗時較長,且能夠並行的操做都封裝成一個FutureTask(好比:有的數據經過調用dubbo服務獲取,有的數據須要從緩存中讀取,有的數據須要複雜的計算) get