3

这可能是非常基本的,但我不是 Java 人。这是我的处理代码,它只是打印和休眠:

    private static void myProcessings(int value)
    {
        System.out.println("Processing " + value);
    
        try
        {
            Thread.sleep(2000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    
        System.out.println("Finished processing " + value);
    }

现在,这个并行流似乎可以并行工作:

    IntStream iit = IntStream.rangeClosed(1,3);
    iit.parallel().forEach(Main::myProcessings);
    
    // output:

    // Processing 2
    // Processing 1
    // Processing 3
    // Finished processing 3
    // Finished processing 2
    // Finished processing 1

但是这个(由迭代器制成)没有:

    static class MyIter implements Iterator<Integer>
    {
        private int max;
        private int current;
    
        public MyIter(int maxVal)
        {
            max = maxVal;
            current = 1;
        }
    
        @Override
        public boolean hasNext()
        {
            return current <= max;
        }
    
        @Override
        public Integer next()
        {
            return current++;
        }
    }
    
    MyIter it = new MyIter(3);
    StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, 0), true)
                 .forEach(Main::myProcessings);

    // output:

    // Processing 1
    // Finished processing 1
    // Processing 2
    // Finished processing 2
    // Processing 3
    // Finished processing 3

我在自定义迭代器版本中做错了什么?(我正在使用 Java 8)

4

1 回答 1

5

一种方法是估计流的大小:

Spliterators.spliterator(it, 3, 0);

数字(此处为 3)不必精确,但如果您给出 10000,则只有一个线程将用于实际大小 3。如果您给出 10,则将使用多个线程,即使大小为3。

估计值(在我的示例中为 3)用于确定批次的大小(在移动到下一个线程之前发送到一个线程的任务数)。如果您提供的估计数量很大并且只提交了几个任务,它们可能会全部分组并在第一个线程上运行,而不会发送任何内容到第二个线程。

于 2020-06-30T10:06:52.793 回答