在Task#onSucceeded中调用Task#是否安全?

时间:2014-07-16 10:15:47

标签: java concurrency javafx

以下两个AssertionErrors是否正确?

final Task<String> myTask = new Task<String>() {
    @Override
    protected String call() throws Exception {
        return "Lorem Ipsum";
    }

    @Override
    protected void succeeded() {
        super.succeeded();
        try {
            final String computedString = get();
        } catch (final InterruptedException | ExecutionException ex) {
            throw new AssertionError(
                    "Expected get() can called safely in succeeded");
        }
    }
};

myTask.setOnSucceeded(e -> {
    try {
        final String computedString = myTask.get();
    } catch (final Exception ex) {
        throw new AssertionError(
                "Expected get() can called safely in onSucceeded");
    }
});

2 个答案:

答案 0 :(得分:0)

succeed()中,您可以确定get()没有阻止。它也不可能获得ExecutionException,因为这会触发failed()

但是你可以获得InterruptedException,因为其他线程可以随时发送此信号。

有关如何处理此特定例外的详细信息,请参阅此问题:Handling InterruptedException in Java

答案 1 :(得分:0)

对setOnSucceeded中的任务调用get()将是安全的,因为在调用成功的回调时,任务已经完成,因此它根本不会阻塞而且不应该显示当时的任何例外。

我认为调用getValue()是首选,因为它的语义似乎更简单。 getValue是非阻塞的,不能抛出InterruptedException或ExecutionException,并确保它只在JavaFX应用程序线程上调用,因此它更容易理解并且有额外的安全检查。