java面试-Java并发编程(九)——批量获取多条线程的执行结果
生活随笔
收集整理的這篇文章主要介紹了
java面试-Java并发编程(九)——批量获取多条线程的执行结果
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
當(dāng)向線程池提交callable任務(wù)后,我們可能需要一次性獲取所有返回結(jié)果,有三種處理方法。
方法一:自己維護(hù)返回結(jié)果
// 創(chuàng)建一個(gè)線程池 ExecutorService executorService = Executors.newFixedThreadPool(10);// 存儲(chǔ)執(zhí)行結(jié)果的List List<Future<String>> results = new ArrayList<Future<String>>();// 提交10個(gè)任務(wù) for ( int i=0; i<10; i++ ) {Future<String> result = executorService.submit( new Callable<String>(){public String call(){int sleepTime = new Random().nextInt(1000);Thread.sleep(sleepTime);return "線程"+i+"睡了"+sleepTime+"秒";}} );// 將執(zhí)行結(jié)果存入results中results.add( result ); }// 獲取10個(gè)任務(wù)的返回結(jié)果 for ( int i=0; i<10; i++ ) {// 獲取包含返回結(jié)果的future對(duì)象Future<String> future = results.get(i);// 從future中取出執(zhí)行結(jié)果(若尚未返回結(jié)果,則get方法被阻塞,直到結(jié)果被返回為止)String result = future.get();System.out.println(result); }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
此方法的弊端:
方法二:使用ExecutorService的invokeAll函數(shù)
本方法能解決第一個(gè)弊端,即并不需要自己去維護(hù)一個(gè)存儲(chǔ)返回結(jié)果的容器。當(dāng)我們需要獲取線程池所有的返回結(jié)果時(shí),只需調(diào)用invokeAll函數(shù)即可。?
但是,這種方式需要你自己去維護(hù)一個(gè)用于存儲(chǔ)任務(wù)的容器。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
方法三:使用CompletionService
CompletionService內(nèi)部維護(hù)了一個(gè)阻塞隊(duì)列,只有執(zhí)行完成的任務(wù)結(jié)果才會(huì)被放入該隊(duì)列,這樣就確保執(zhí)行時(shí)間較短的任務(wù)率先被存入阻塞隊(duì)列中。
ExecutorService exec = Executors.newFixedThreadPool(10);final BlockingQueue<Future<Integer>> queue = new LinkedBlockingDeque<Future<Integer>>( 10); //實(shí)例化CompletionService final CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>( exec, queue); // 提交10個(gè)任務(wù) for ( int i=0; i<10; i++ ) {executorService.submit( new Callable<String>(){public String call(){int sleepTime = new Random().nextInt(1000);Thread.sleep(sleepTime);return "線程"+i+"睡了"+sleepTime+"秒";}} ); }// 輸出結(jié)果 for ( int i=0; i<10; i++ ) {// 獲取包含返回結(jié)果的future對(duì)象(若整個(gè)阻塞隊(duì)列中還沒(méi)有一條線程返回結(jié)果,那么調(diào)用take將會(huì)被阻塞,當(dāng)然你可以調(diào)用poll,不會(huì)被阻塞,若沒(méi)有結(jié)果會(huì)返回null,poll和take返回正確的結(jié)果后會(huì)將該結(jié)果從隊(duì)列中刪除)Future<String> future = completionService.take();// 從future中取出執(zhí)行結(jié)果,這里存儲(chǔ)的future已經(jīng)擁有執(zhí)行結(jié)果,get不會(huì)被阻塞String result = future.get();System.out.println(result); }總結(jié)
以上是生活随笔為你收集整理的java面试-Java并发编程(九)——批量获取多条线程的执行结果的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ffmpeg使用总结
- 下一篇: PostgreSQL触发器的使用