1. 程式人生 > >Java中Callable和Future——引子

Java中Callable和Future——引子

一、場景

通常我們在一個事件方法中會去呼叫另外幾個方法,如發用郵件,為了快速響應,一般最簡單直接粗暴的是
新啟一執行緒來非同步發郵件(使用執行緒池較好)。這個時候我們不太在意所依賴的方法操作成功與否(即不需要結果)。

但,多半我們是需要非同步操作結果的。比如在Action層呼叫多個Service或在Service層方法中呼叫多個DAO。如下圖,假設某Action層方法需要依賴呼叫a、b、c三個方法,它們三分別耗時10ms、15ms、20ms,這樣序列順序執行下來,即總共需要45ms。
這裡寫圖片描述

有木有辦法縮短這個耗時呢?

二、方法

如果使a、b、c併發執行,怎麼樣?那麼總共耗時就是這三個中耗時最長的那一個即20ms。如下圖:
這裡寫圖片描述

我們知道執行緒Runnable介面是沒返回結果的。看看下面的Callable和Future簡單模擬實現:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**  
 *
 * @author : Ares.yi
 * @createTime : 2014-11-10 上午11:13:42 
 * @version : 1.0 
 * @description
: * */
public class TestFuture { private final ExecutorService pool = Executors.newFixedThreadPool(2); public int getData() throws Exception{ int i = invoke1(); int j = invoke2(); return i+j; } public int getData2() throws Exception{ Future<Integer> f1 = null
; Future<Integer> f2 = null; f1 = pool.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { return invoke1(); } }); f2 = pool.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { return invoke2(); } }); int i = f1.get();//會阻塞 int j = f2.get(); pool.shutdown(); return i+j; } public static void main(String[] args) throws Exception { TestFuture obj = new TestFuture(); long start = System.currentTimeMillis(); obj.getData2(); long end = System.currentTimeMillis(); System.out.println(end-start); } private static int invoke1() throws InterruptedException{ Thread.sleep(3000); return 1; } private static int invoke2() throws InterruptedException{ Thread.sleep(2000); return 2; } }

三、延伸

如果c需要依賴a和b的結果呢,怎麼辦?
這裡寫圖片描述

請見最後一篇。