callable能夠返回運行結果,經過FutureTask去接收這個結果。使用方法爲java
FutureTask task = new FutureTask(new Callable);ide
new Thread(task).start();spa
去拿callable的返回值時,調用task.get()方法調用,若是call方法尚未執行結束,該線程就會被阻塞住,因此最好設置一個超時時間。線程
另外值得一提的是,futuretask能夠覆蓋一個done方法,當call方法執行結束以後,會自動調用done方法。詳細demo以下:code
public static void main(String[] args) throws Exception { // ExecutorService service = Executors.newCachedThreadPool(); Callable<String> callable = new Callable<String>() { @Override public String call() throws Exception { System.out.println("執行callable方法"); Thread.sleep(5000); return "執行成功"; } }; MyFuture future = new MyFuture(callable); new Thread(future).start(); System.out.println("拿到返回值是:" + future.get()); } public static class MyFuture extends FutureTask { public MyFuture(Callable callable) { super(callable); } @Override protected void done() { System.out.println("callable方法執行成功,我這個done方法被觸發了"); } }
執行結果以下:隊列
public static void main(String[] args) throws Exception { ExecutorService service = Executors.newCachedThreadPool(); Callable<String> callable = new Callable<String>() { @Override public String call() throws Exception { System.out.println("執行callable方法"); Thread.sleep(5000); return "執行成功"; } }; Future future = service.submit(callable); System.out.println("拿到返回值是:" + future.get()); }
執行結果:get
日常咱們要拿到一組線程池的處理結果,有一種方法是定義一個List<Future>,而後將每一個任務處理的Future加入到這個list裏面,而後循環這個List裏的每一個Future去future.get(),可是這樣作有個很差的地方在於,假如我此次future正好是處理最後一個才結束,這期間內其餘的任務都已經處理結束了,可是因爲這個沒結束,我一直被阻塞住。而這時候能夠利用CompletionService,利用這個類,能夠依次拿到最新處理結束的任務。實現的原理是經過FutureTask,FutureTask能夠在任務執行完畢以後處理done方法,而後CompletionService會建立一個隊列,當每一個futuretask處理完畢,將結果放入這個對列,而後service一直在take,當隊列裏有結果的時候就拿走一個(簡直就是生產者消費者模式)it