java~并行計算~Future和Callable實現(xian)大任務的并行處理
Callable是一個泛型接口,也是一個FunctionalInterface,即函數(shu)式接(jie)口(kou),它(ta)可以(yi)使用在(zai)Lambda表達式上,即現(xian)在(zai)比較(jiao)流行的(de)函數(shu)式編程(cheng)(cheng),其實java8之后,封裝了(le)好多函數(shu)式接(jie)口(kou),今天說的(de)Callable它(ta)是(shi)一個(ge)(ge)帶有(you)返回(hui)值的(de)接(jie)口(kou),它(ta)主要(yao)和Future一起(qi)使用,用在(zai)并(bing)(bing)(bing)行計算(suan)(suan)上;并(bing)(bing)(bing)行計算(suan)(suan)就是(shi)說,一個(ge)(ge)大任務,多個(ge)(ge)線程(cheng)(cheng)并(bing)(bing)(bing)發執(zhi)行,這樣可以(yi)縮減程(cheng)(cheng)序運行的(de)時間(jian),當然前提(ti)是(shi)你要(yao)保持線程(cheng)(cheng)的(de)安全性。
大任務實現類
/**
* 干一件不好干的事,使用Callable接口,需要 FutureTask實現類的支持,用于接收運算結果.
*/
class DoWork implements Callable<Integer> {
/**
* 需要處理的對象集合,每個線程傳遞自己的對象.
*/
List<String> list;
public DoWork(List<String> list) {
this.list = list;
}
@Override
public Integer call() throws Exception {
for (String s : list) {
System.out.println(Thread.currentThread().getId() + ":" + s);
}
Thread.sleep(3000);
return 1;
}
}
主方法中拆分大對象,調用大任務方法
@GetMapping("/do-fast")
public void doFast() throws InterruptedException, ExecutionException {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ExecutorService executor = Executors.newFixedThreadPool(2);
List<Future<Integer>> results = executor.invokeAll(asList(
new DoWork(Arrays.asList("a","b")), new DoWork(Arrays.asList("c","d"))
));
executor.shutdown();
//合并結果
for (Future<Integer> result : results) {
System.out.println(result.get());
}
stopWatch.stop();
System.out.println(stopWatch.getLastTaskTimeMillis());
}
如果不使用并行計算,這兩個方法執行應該是3秒+3秒=6秒,而使用了并行編程,它只有3秒左右
