Java 并发编程 - 死循环

Java concurrent programming - endless loop

我正在读 Introducing Play Framework: Java Web Application Development (ISBN 978-1-4842-5645-9) 一书,这个例子在Callable:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class CallableClient {
    /**
     * @param args
     */

    // Step1 : Create a Runnable
    public static void main(String[] args) {
        Callable callableTask = new CallableTask();
        // Step 2: Configure Executor
        // Uses FixedThreadPool executor
        ExecutorService executor = Executors.newFixedThreadPool(2);
        Future<String> future = executor.submit(callableTask);
        boolean listen = true;
        while (listen) {
            if (future.isDone()) {
                String result;
                try {
                    result = future.get();
                    listen = false;
                    System.out.println(result);
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }
        executor.shutdown();
    }
}

我的问题是,如果 Future 的计算抛出异常,while 会永远循环 运行 吗?


在我看来,是的,它将永远循环。

首先,如果Future计算抛出异常,那么

始终计算为 true。所以我们到达了if的内部,这里可以设置停止条件。还可以。

其次,根据未来documentation,到达第

行时

它总是会抛出 ExecutionException 因为计算抛出了异常。这个异常是在try-catch块中捕获的,没有达到停止条件precondition,也就是

最后,以上将创建一个无限循环。

是我的假设有误还是这个例子的作者真的错了?

上面提到的程序永远循环,如果可调用对象抛出异常。


这是一个包含抛出异常的可调用代码片段。永远执行已编译的片段循环。

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;


public class CallableClient {

    public static class CallableTask implements Callable<String> {

        @Override
        public String call() throws Exception {
            throw new Exception();
        }
    }

    public static void main(String[] args) {
        Callable<String> callableTask = new CallableTask();
        ExecutorService executor = Executors.newFixedThreadPool(2);
        Future<String> future = executor.submit(callableTask);
        boolean listen = true;
        while (listen) {
            if (future.isDone()) {
                String result;
                try {
                    result = future.get();
                    listen = false;
                    System.out.println(result);
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }
        executor.shutdown();
    }
}