我們在前面的總結中的所有的線程的使用,大家有沒有覺的有一個問題就是我們得不到線程的執行的返回的結果,這個是不是有點然人懊惱,對的我們只是創建了線程去執行,但是我們沒有獲取到他的返回值,在有些時候這個是不必須的,但是如果我們 需要線程的執行結果呢,我們需要線程的執行結果加以運算之類的,怎麼辦,彆着急,我們還有方法可以取到線程的執行結果的,那就是Callable,Callable就是幫助我們獲取到線程的執行結果,我們在使用Callable的時候需要重寫他的Call()方法.在使用Callable的時候我們配合的使用Future,那麼我們就可達到這樣的效果:我們的線程在執行一些費時的操作,我們可以先把線程裝進我們的一個容器裏,等到我們需要的時候我們直接從容器中取結果就OK;下面我們來看下我們的代碼
public class CallableAndFuture { public static void main(String[] args) { //創建一個線程返回隨機的Int值 Callable callable = new Callable() { @Override public Object call() throws Exception { return new Random().nextInt(); } }; FutureTask task = new FutureTask(callable); new Thread(task).start(); try { //等待的結果我們可以做很多事情 Thread.sleep(5000); //阻塞等待 結果返回 System.out.println(task.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }我們可以看到我們時候用的是 FutureTask 這個容器來裝在我們的線程,最後調用他的Task方法就可以取得線程執行的結果了.FutureTask實現了Runable接口和Future接口,那麼說名他可以執行我們的線程也可以獲取我們線程的執行 結果,Future裏面有很多的線程相關的方法,大家可以進去看看源碼,檢測函數和獲取結果函數等等
下面我們在使用一個線程池的方式來卡看我們的Callable和Future的使用:
public class CallableAndFutrue2 { public static void main(String[] args) { //創建一個線程池,需要幾個就創建幾個的線程池 ExecutorService service = Executors.newCachedThreadPool(); //用來存儲線程結果 List<Future> futures = new ArrayList<Future>(); //創建5個線程加入隊列阻塞獲取 for (int i = 0; i < 5; i++) { Callable callable = new Callable() { @Override public Object call() throws Exception { return new Random().nextInt(); } }; Future future = service.submit(callable); futures.add(future); } for (Future future : futures) { try { System.out.println(future.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } } }我們 創建一個Future容器來裝在我們的線程執行結果,最後遍歷這個容器就可以取得結果了.我們 使用的是上一節我們總結的newCachedThreadPoll當時創建的線程池.