以上內容出自:https://www.cnblogs.com/hzjjames/p/java_timeout.html;
但是遇到一個idea自動提示的錯誤,如下圖:
線程池不允許使用Executors去創建,而是通過ThreadPoolExecutor的方式,這樣的處理方式讓寫的同學更加明確線程池的運行規則,規避資源耗盡的風險。 說明:Executors各個方法的弊端:
官方更推薦用ThreadPoolExecutor的方式手動創建線程池。
於是將上面的代碼改爲:
ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(20);
ExecutorService executorService = new ThreadPoolExecutor(3, 5, 50, TimeUnit.MILLISECONDS, queue);
警告消除。
ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(20);
ExecutorService executorService = new ThreadPoolExecutor(3, 5, 50, TimeUnit.MILLISECONDS, queue);
// ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
Future<String> future = executorService.submit(() -> {
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("任務被中斷");
}
return "OK";
});
try {
future.get(5, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
// 參數爲true則會強制interrupt中斷
future.cancel(true);
e.printStackTrace();
System.out.println("任務超時");
return "任務超時";
} finally {
System.out.println("清理資源");
}
代碼解讀:
一、callable是函數式接口,可以用lambda表達式簡化書寫:
二、future.cancle();
future.cancel(true);參數可以爲false和true,參數爲true則會強制interrupt中斷正在執行的任務。
控制檯打印任務中斷異常:
三、TimeUnit.SECONDS.sleep(10);
底層調用的還是Thread.sleep()方法:
參考鏈接:
1.futureTask解讀:https://www.cnblogs.com/maypattis/p/5827671.html
2.Executor、Executors、ExecutorService:https://blog.csdn.net/weixin_40304387/article/details/80508236
3.Thread.sleep()和TimeUnit.SECONDS.sleep()的區別與聯繫:https://www.cnblogs.com/sanhuan/p/4826401.html