Java 8 parallelStream findFirst

FaN*_*NaJ 5 java parallel-processing java-8

假设我们有一个像这样的工人列表:

List<Worker> workers = new ArrayList<>();
workers.add(new Worker(1));
workers.add(new Worker(2));
workers.add(new Worker(3));
workers.add(new Worker(4));
workers.add(new Worker(5));
Run Code Online (Sandbox Code Playgroud)

我想找到第一个完成工作的工人,所以:

Worker first = workers.parallelStream().filter(Worker::finish).findFirst().orElse(null);
Run Code Online (Sandbox Code Playgroud)

但是有一个问题,我不想等待所有工人完成他们的工作然后找到第一个,但第一个工人一完成他的工作!

public class Test {

    public static void main(String[] args) {
        List<Worker> workers = new ArrayList<>();
        workers.add(new Worker(1));
        workers.add(new Worker(2));
        workers.add(new Worker(3));
        workers.add(new Worker(4));
        workers.add(new Worker(5));
        Worker first = workers.parallelStream().filter(Worker::finish).findFirst().orElse(null);
        if (first != null) {
            System.out.println("id : " + first.id);
        }
    }

    static class Worker {

        int id;

        Worker(int id) {
            this.id = id;
        }

        boolean finish() {
            int t = id * 1000;
            System.out.println(id + " -> " + t);
            try {
                Thread.sleep(t);
            } catch (InterruptedException ignored) {
            }
            return true;
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

有没有办法实现它java.util.Stream

谢谢.

Era*_*ran 2

当您使用您的finish方法作为 Stream 的过滤器时,这意味着为了评估特定 Worker 的过滤器谓词,该 Worker 必须完成其工作。

但是,当您将此代码作为并行流运行时,过滤器可能会同时应用于多个工作器,在这种情况下,第一个完成的工作器将为您提供输出。但是,您无法控制并行 Stream 将使用多少个线程。它可能决定某些 Worker 应该在同一线程上处理,在这种情况下,其中一些根本不会被处理(因为您的终端操作要求只有一个 Worker 完成其处理)。

因此,如果您的目标是finish同时为所有 Worker 执行,则不能使用 Stream(甚至不能使用并行 Stream)。