提交任务有execute()
和submit()
两个方法,下面看看他俩的区别:
接收参数不同
execute()的参数只有Runnable
;
submit()既可以提交Runnable
类型的任务,也可以提交Callable
类型的任务。
返回值不同
execute() 没有返回值;
submit() 有返回值Future
。通过Future可以获取各个线程的完成情况,是否有异常,还能试图取消任务的执行。
异常处理不同
execute()在执行任务时,如果遇到异常会直接抛出;
submit()不会直接抛出,只有在使用Future#get
方法获取返回值时,才会抛出异常。
假设我有很多更新各种数据的task,我希望如果其中一个task失败,其它的task就不需要执行了。那我就需要catch
Future#get
抛出的异常,然后终止其它task的执行。
下面看个使用submit()获取返回值的例子:
public static void main(String[] args) {
// 创建固定大小的线程池
// return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
System.out.println("threadPool start...");
// 提交任务 submit(Callable<T> task), 获取 任务的future
Future<Integer> future = threadPool.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
try {
// 主动触发算术异常
// int a = 10 / 0;
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 111;
}
});
// 通过 future#isDone 可以 查看 task 线程是否完成;
// 其实,只要 task 的 call 方法结束,
// 1 无论是 正常结束, 还时 异常结束,都代表任务已经结束,统一返回true
// 通过 future#get 可以 得到 task线程的返回值;
// get 方法是同步阻塞方法,会阻塞到任务结束为止,
// 1 一般和future#isDone 配合使用,轮询任务的状态
// 2 如果 任务线程中途 (被取消,发生异常,被中断),get 方法都会抛出异常
Integer value = -1;
try {
// 轮询判断任务是否完成
for (; ; ) {
// 如果 任务完成
if (future.isDone()) {
// 阻塞到任务完成为止
// 这里 不会诸塞,因为任务明显完成了
value = future.get();
System.out.println("任务顺利完成,future#isDone=" + future.isDone() + ", 返回值=" + value);
break;
} else {
// 任务未完成
System.out.println("任务未完成, future#isDone=" + future.isDone());
Thread.sleep(1000);
}
}
} catch (InterruptedException | ExecutionException e) {
// 任务发生异常,future#isDone 返回 true
System.out.println("任务执行期间发生异常, future#isDone=" + future.isDone() +", 返回值=" + value);
e.printStackTrace();
}
// 等待其他任务完成,最后才关闭线程池
threadPool.shutdown();
System.out.println("end。。。");
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/69740.html