分享
三行代码  ›  专栏  ›  技术社区  ›  ABadHaiku

当一个Java8流.forEach()完成迭代?

  •  0
  • ABadHaiku  · 技术社区  · 1 周前

    我想使用Java8的并行性 Stream 但我也需要按照特定的顺序进行某些操作,否则一切都会中断。问题是,使用流意味着代码现在是异步的,我不知道只有在完成对整个集合的迭代后,如何使某些事情发生。

        public void iterateOverMap(Map<String, String> m)
        {
            AtomicInteger count = new AtomicInteger(0);
            
            m.keySet().stream().forEach((k) -> {
                        Object o = m.get(k);
                        
                        // do stuff with o
                        
                        count.incrementAndGet();
                    });
            
            // spin up a new thread to check if the Stream is done
            new Thread(() -> {
                for (;;)
                {
                    if (count.intValue() >= map.size())
                        break;
                }
                afterFinishedIterating();
            }).start();
        }
    

    我不喜欢为了跟踪这件事而不得不启动一个新线程或阻塞主线程的想法,但我想不出还能怎么做。有人知道更好的选择吗?

    1 回复  |  直到 1 周前
        1
  •  1
  •   Yassin Hajaj    1 周前

    Stream 处理是同步的。

    如果你想举例说明如何跟踪 溪流 ,您可以使用 peek() 中间操作,但请记住,它最好用于调试目的

    取自 my other answer

    Stream<MyData> myStream = readData();
    final AtomicInteger loader = new AtomicInteger();
    int fivePercent = elementsCount / 20;
    MyResult result = myStream
        .map(row -> process(row))
        .peek(stat -> {
            if (loader.incrementAndGet() % fivePercent == 0) {
                System.out.println(loader.get() + " elements on " + elementsCount + " treated");
                System.out.println((5*(loader.get() / fivePercent)) + "%");
            }
        })
        .reduce(MyStat::aggregate);
    
        2
  •  0
  •   ABadHaiku    1 周前

    Collections.synchronizedList(new LinkedList<>()) “我使用的列表,不是 Stream 用法。 它不像我假设的那样是异步的,所以答案是“你不必这样做,它是为你做的”。