【轉】Java線程系列:Callable和Future

來源:互聯網
上載者:User

標籤:[]   sig   pre   task   cal   說明   研究   類型   .net   

一、前言

  在研究JDK1.8的CompletableFuture時,順道將Futrue一起掃了盲~這篇博文純轉載

二、本文

   本篇說明的是Callable和Future,它倆很有意思的,一個產生結果,一個拿到結果。 
       Callable介面類似於Runnable,從名字就可以看出來了,但是Runnable不會返回結果,並且無法拋出返回結果的異常,而Callable功能更強大一些,被線程執行後,可以傳回值,這個傳回值可以被Future拿到,也就是說,Future可以拿到非同步執行任務的傳回值,下面來看一個簡單的例子:

  

public class CallableAndFuture {    public static void main(String[] args) {        Callable<Integer> callable = new Callable<Integer>() {            public Integer call() throws Exception {                return new Random().nextInt(100);            }        };        FutureTask<Integer> future = new FutureTask<Integer>(callable);        new Thread(future).start();        try {            Thread.sleep(5000);// 可能做一些事情            System.out.println(future.get());        } catch (InterruptedException e) {            e.printStackTrace();        } catch (ExecutionException e) {            e.printStackTrace();        }    }}

  FutureTask實現了兩個介面,Runnable和Future,所以它既可以作為Runnable被線程執行,又可以作為Future得到Callable的傳回值,那麼這個組合的使用有什麼好處呢?假設有一個很耗時的傳回值需要計算,並且這個傳回值不是立刻需要的話,那麼就可以使用這個組合,用另一個線程去計算傳回值,而當前線程在使用這個傳回值之前可以做其它的操作,等到需要這個傳回值時,再通過Future得到,豈不美哉!這裡有一個Future模式的介紹:http://openhome.cc/Gossip/DesignPattern/FuturePattern.htm。 
       下面來看另一種方式使用Callable和Future,通過ExecutorService的submit方法執行Callable,並返回Future,代碼如下:

  

public class CallableAndFuture {    public static void main(String[] args) {        ExecutorService threadPool = Executors.newSingleThreadExecutor();        Future<Integer> future = threadPool.submit(new Callable<Integer>() {            public Integer call() throws Exception {                return new Random().nextInt(100);            }        });        try {            Thread.sleep(5000);// 可能做一些事情            System.out.println(future.get());        } catch (InterruptedException e) {            e.printStackTrace();        } catch (ExecutionException e) {            e.printStackTrace();        }    }}

  代碼是不是簡化了很多,ExecutorService繼承自Executor,它的目的是為我們管理Thread對象,從而簡化並發編程,Executor使我們無需顯示的去管理線程的生命週期,是JDK 5之後啟動任務的首選方式。 
       執行多個帶傳回值的任務,並取得多個傳回值,代碼如下:

  

public class CallableAndFuture {    public static void main(String[] args) {        ExecutorService threadPool = Executors.newCachedThreadPool();        CompletionService<Integer> cs = new ExecutorCompletionService<Integer>(threadPool);        for(int i = 1; i < 5; i++) {            final int taskID = i;            cs.submit(new Callable<Integer>() {                public Integer call() throws Exception {                    return taskID;                }            });        }        // 可能做一些事情        for(int i = 1; i < 5; i++) {            try {                System.out.println(cs.take().get());            } catch (InterruptedException e) {                e.printStackTrace();            } catch (ExecutionException e) {                e.printStackTrace();            }        }    }} 

  其實也可以不使用CompletionService,可以先建立一個裝Future類型的集合,用Executor提交的任務傳回值添加到集合中,最後遍曆集合取出資料,代碼略。更新於2016-02-05。這裡再闡述一下:提交到CompletionService中的Future是按照完成的順序排列的,這種做法中Future是按照添加的順序排列的

三、連結

  1、http://blog.csdn.net/ghsau/article/details/7451464

四、聯絡本人

  為方便沒有部落格園帳號的讀者交流,特意建立一個企鵝群,讀者如果有對博文不明之處,歡迎加群交流:261746360,小杜比亞-部落格園

【轉】Java線程系列:Callable和Future

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.