缺少引發檢查異常的情況更為嚴重。 合同是public void run() ,這意味著您必須捕獲受檢查的異常并對其進行處理。 即使您很小心并且將它們存儲起來以供以后驗證,也不能強制所有使用此類的類來檢查異常。 您可以遍歷所有的獲取器,并在每個異常中都存在異常時拋出該異常 。 除了麻煩之外,即使那也不是萬無一失的。 您無法強制調用其中任何一個。 線程程序員會正確地調用join()以等待它完成,然后可能會繼續前進。
不過不用擔心,多年之后,終于在1.5版本中解決了這個問題。 通過在上一篇文章中討論的Callable和Future接口的引入以及它們在線程池中的支持,這兩個問題都得到了很好的解決。
可召回
Callable接口聲明公共T call()拋出Exception 。 現在我們可以返回結果,將其強類型化為實現中聲明的類型,甚至拋出Exceptions 。 盡管Executors類中有一些實用程序方法可以如第3部分中所述轉換您的Runnable實例,但最好還是回顧一下您當前對Runnable或Thread子類的實現。 何必呢? 主要是為了仔細檢查并刪除可能為解決缺少對拋出的異常的支持而實施的變通方法。 同時,您可能希望利用在執行方法中直接返回結果的功能,而無需進行強制轉換以檢索值。
未來
這是線程池和Callable的組合功能在一起的地方。 Future是1.5中引入的另一個新接口。 當您向一個線程池提交Callable時 ,將為您提供Future的實例,該實例的類型將傳遞給您傳入的Callable 。此對象替代您在1.5之前使用的實際Thread實例。 以前您必須執行Thread.join()或Thread.join(long millis) ,現在您可以像本例中那樣使用它們。
public class ServerAcceptingRequestsVerifier implements Callable {/*** @return Boolean.TRUE is server is accepting requests* Boolean.FALSE otherwise*/public Boolean call() throws Exception {Boolean isAcceptingRequests = null;... ask server about taking requests herereturn isAcceptingRequests;}
}
public Boolean isServerTakingRequests(String server)throws UnresponsiveException, InterruptedException {ServerAcceptingRequestsVerifier acceptingRequestsVerifier =new ServerAcceptingRequestsVerifier();Future future =THREAD_POOL.submit(acceptingRequestsVerifier);try {Boolean isAcceptingRequests = future.get();//waits for the thread to complete, even if it hasn't startedreturn isAcceptingRequests;} catch (ExecutionException e) {throw new UnresponsiveException(e.getCause());}}
如果決定限制愿意等待完成的時間,那么現在有了顯式的TimeoutException也很好。
try {Boolean isAcceptingRequests = future.get(5, TimeUnit.SECONDS);//this waits for 5 seconds, throwing TimeoutException if not donereturn isAcceptingRequests;
} catch (TimeoutException e) {LOGGER.warn("Timed out waiting for server check thread." +"We'll try to interrupt it.");future.cancel(true);return Boolean.FALSE;
} catch (ExecutionException e) {throw new UnresponsiveException(e.getCause());
}
在我們的下一篇文章中,我們將介紹一些用于使線程池正常工作的新接口/類,這些接口/類也可供我們使用。
參考:我們的JCG合作伙伴在Carfey Software博客上提供的 Java Concurrency Part 4 – Callable,Future 。
- Java并發教程–信號量
- Java并發教程–重入鎖
- Java并發教程–線程池
- Java并發教程–阻塞隊列
- Java并發教程– CountDownLatch
- Exchanger和無GC的Java
- Java Fork / Join進行并行編程
- 使用迭代器時如何避免ConcurrentModificationException
- 改善Java應用程序性能的快速技巧
翻譯自: https://www.javacodegeeks.com/2011/09/java-concurrency-tutorial-callable.html