多執行緒之Future使用詳解
阿新 • • 發佈:2018-11-26
什麼是Future
Future是一個未來物件,裡面儲存這執行緒處理結果,它像一個提貨憑證,拿著它你可以隨時去提取結果
什麼時候使用
在兩種情況下,離開Future幾乎很難辦。
- 一種情況是拆分訂單,比如你的應用收到一個批量訂單,此時如果要求最快的處理訂單,那麼需要併發處理,併發的結果如何收集,這個問題如果自己去程式設計將非常繁瑣,此時可以使用CompletionService解決這個問題。CompletionService將Future收集到一個佇列裡,可以按結果處理完成的先後順序進隊。
- 另外一種情況是,如果你需要併發去查詢一些東西(比如爬蟲),併發查詢只要有一個結果返回,你就認為查詢到了,並且結束查詢,這時也需要用CompletionService和Future來解決。
使用過程既可以用CompletionService,也可以自己維護一個list將Future新增進去。
區別是:CompletionService是先完成的先返回,自己維護的list就是按順序一個個取值
示例程式碼:
public class FutureDemo {
private static class Task implements Callable<String> {
@Override
public String call() throws Exception {
// 模擬真實事務的處理過程,這個過程是非常耗時的。
Thread.sleep(5000);
return "call return " + Thread.currentThread().getName();
}
}
public static void main(String[] args) throws Exception {
FutureDemo demo =new FutureDemo();
demo.testComplete();
// demo.testFutrue();
}
private void testFutrue() throws Exception{
List<Future<String>> futures = new ArrayList<Future<String>>();
ExecutorService executorService = Executors.newCachedThreadPool();
System.out.println("已經提交資源申請");
for (int i = 0; i < 10; i++) {
futures.add(executorService.submit(new Task()));
}
for (Future<String> future : futures) {
if (!future.isDone()) {
System.out.println("資源還沒有準備好");
}
System.out.println(future.get());
}
executorService.shutdown();
}
private void testComplete() throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool();
CompletionService<String> ecs = new ExecutorCompletionService<>(executorService);
System.out.println("已經提交資源申請");
int lenth =10;
for (int i = 0; i < lenth; i++) {
ecs.submit(new Task());
}
//CompletionService會按處理完後順序返回結果
List<String> res =new ArrayList<>();
for(int i = 0;i<lenth;i++ ){
Future<String> f = ecs.take();
System.out.println(f.get());
}
executorService.shutdown();
}
}