Java中Callable和Future——引子
阿新 • • 發佈:2019-02-10
一、場景
通常我們在一個事件方法中會去呼叫另外幾個方法,如發用郵件,為了快速響應,一般最簡單直接粗暴的是
新啟一執行緒來非同步發郵件(使用執行緒池較好)。這個時候我們不太在意所依賴的方法操作成功與否(即不需要結果)。
但,多半我們是需要非同步操作結果的。比如在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的結果呢,怎麼辦?
請見最後一篇。