为了账号安全,请及时绑定邮箱和手机立即绑定

当可运行对象抛出异常时 Future<T>.get() 卡住 - 在单独的执行程序服务上运行时?

当可运行对象抛出异常时 Future<T>.get() 卡住 - 在单独的执行程序服务上运行时?

holdtom 2022-01-12 16:38:41
这里有一个再现:import java.util.concurrent.*;public class Main {    public static void main(String[] args) throws ExecutionException, InterruptedException {        System.out.println("Hello!");        ExecutorService exec = Executors.newSingleThreadExecutor();        Future<Integer> f = exec.submit(() -> x());        f.get();        System.out.println("f.get() returned");        exec.shutdownNow();        System.out.println("Good bye!");    }    private static Integer x() {        throw new RuntimeException("An unfortunate event");    }}输出只显示“你好!” 和异常堆栈跟踪,然后让程序永远挂起。下面的更改可以解决该问题,但是知道为什么执行会挂在上面的代码中吗?使用公共线程池不会挂起:Future<Integer> f = ForkJoinPool.commonPool().submit(() -> x());将调用包装在 try/catch 周围可以让应用程序正常退出:Future<Integer> f = exec.submit(() -> x());try {    f.get();} catch (Exception ex) {    ex.printStackTrace();}
查看完整描述

1 回答

?
桃花长相依

TA贡献1860条经验 获得超8个赞

总是很难找到一个很好的例子try-finally及其适当的用法。我认为是这样。


try {

    f.get();

    System.out.println("f.get() returned");

} finally {

    exec.shutdownNow();

}

抛出的异常f.get();没有处理,主线程失败。但是该应用程序仍然包含ExecutorService您无法直接访问的非守护线程。


查看完整回答
反对 回复 2022-01-12
  • 1 回答
  • 0 关注
  • 259 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信