猿问

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

这里有一个再现:


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();

}


holdtom
浏览 260回答 1
1回答

桃花长相依

总是很难找到一个很好的例子try-finally及其适当的用法。我认为是这样。try {&nbsp; &nbsp; f.get();&nbsp; &nbsp; System.out.println("f.get() returned");} finally {&nbsp; &nbsp; exec.shutdownNow();}抛出的异常f.get();没有处理,主线程失败。但是该应用程序仍然包含ExecutorService您无法直接访问的非守护线程。
随时随地看视频慕课网APP

相关分类

Java
我要回答