如何在两个返回布尔值的并行线程上用Java进行短路评估?

MZB*_*MZB 6 java lazy-evaluation short-circuiting java.util.concurrent threadpool

我正在寻找逻辑上等同于以下问题的指导:

public boolean parallelOR() {
    ExecutorService executor = Executors.newFixedThreadPool(2);
    Future<Boolean> taskA = executor.submit( new SlowTaskA() );
    Future<Boolean> taskB = executor.submit( new SlowTaskB() );

    return taskA.get() || taskB.get(); // This is not what I want
    // Exception handling omitted for clarity
 }
Run Code Online (Sandbox Code Playgroud)

上述结构给出了正确的结果,但是即使从taskB完成后结果已知,总是等待taskA完成.

有没有更好的结构,如果任何一个线程返回true而不等待第二个线程完成,它将允许返回一个值?

(涉及的平台是Android,如果这会影响结果).

Col*_*lin 2

这是使用 ParallelOr 的实现ExecutorCompletionService。它等待任务直到任务返回true。如果没有,它最终会返回false

public class ParallelOr {

    static class LongTask implements Callable<Boolean> {

        private int milliseconds;
        private boolean val;

        public LongTask(int milliseconds, boolean val) {
            this.milliseconds = milliseconds;
            this.val = val;
        }

        @Override
        public Boolean call() throws Exception {
            try {
                Thread.sleep(milliseconds);
            } catch(Exception ex) {}
            return val;
        }
    }

    static boolean ParallelOr(List<Callable<Boolean>> tasks) {
        ExecutorService pool = Executors.newFixedThreadPool(tasks.size());
        ExecutorCompletionService<Boolean> completionService
                = new ExecutorCompletionService<Boolean>(pool);

        for(Callable<Boolean> task : tasks) {
            completionService.submit(task);
        }

        for(int i = 0; i < tasks.size(); i++) {
            try {
                Future<Boolean> result = completionService.take();
                if(result.get()) {
                    return true;
                }
            } catch (InterruptedException e) {
            } catch (ExecutionException e) {}
        }

        return false;
    }


    public static void main(String[] args) {
        ArrayList<Callable<Boolean>> tasks = new ArrayList<Callable<Boolean>>();

        tasks.add(new LongTask(1000, true));
        tasks.add(new LongTask(500, false));
        tasks.add(new LongTask(6000, false));

        boolean result = ParallelOr(tasks);

        System.out.println(result);
    }
}
Run Code Online (Sandbox Code Playgroud)

感谢@Lav 指出了该ExecutorCompleteionService课程。