Callable與Future的做用:程序啓動一個線程,線程運行完之後有一個返回結果,它能夠得到線程運行完以後的返回結果,經過代碼看看效果。java
- import java.util.*;
- import java.util.concurrent.*;
- public class CallableAndFuture {
- public static void main(String[] args) {
- ExecutorService threadPool= Executors.newSingleThreadExecutor();//單線程
- Future<String> future=//submit提交返回的結果,類型是Callable返回的類型
- threadPool.submit(//提交一個任務
- new Callable<String>() {
- public String call() throws Exception {
- Thread.sleep(2000);
- return "hello";//返回的類型是String
- };
- }
- );
- System.out.println("等待結果");
- try {
- System.out.println("拿到結果"+future.get());//future.get()獲取返回的結果
- //回來看一下看是否有結果,沒有的話拋出異常(線程去幹別的事了,而不用一直等待結果)
- //System.out.println("拿到結果"+future.get(1,TimeUnit.SECONDS));
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (ExecutionException e) {
- e.printStackTrace();
- }
- /* CompletionService<V>用於提交一組Callable任務,其take方法返回已完成的一個
- Callable任務對應的Future對象,比如我同是種了幾塊地麥子,而後就等待收割,收割
- 時,則是那塊先成熟了,先去收割那塊麥子,而不是哪一塊先種,先去收個哪一塊。
- */
- ExecutorService threadPool2= Executors.newFixedThreadPool(10);//newFixedThreadPool(10)固定大小的線程池,10個
- //CompletionService<V>是一個接口,應該New它的子類
- //將線程池傳遞進去執行它的任務
- CompletionService<Integer> completionService=new ExecutorCompletionService<Integer>(threadPool2);
- for (int i = 1; i <= 10; i++) {//提交10任務
- final int seq=i;//任務的序號
- completionService.submit(new Callable<Integer>() {//submit()提交任務
- @Override
- public Integer call() throws Exception {
- Thread.sleep(new Random().nextInt(5000));//每隔任務不超過5秒
- return seq;//返回任務的序號
- }
- });
- }
- //等待收穫completionService返回的結果
- for (int i = 0; i < 10; i++) {//10個任務,須要拿10遍
- try {
- System.out.println(
- completionService.take().get());//打印返回的結果
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (ExecutionException e) {
- e.printStackTrace();
- }
- }
- }
- }
程序運行的結果:dom
從以上運行結果能夠看出,返回了提交的10的任務的編號。上述代碼的總體執行思路:產生線程————向線程提交任務————任務運行完以後,返回任務的結果————獲取任務的結果。ide