Java parallel stream: how to wait for threads for a parallel stream to finish?

前端 未结 3 1072
梦谈多话
梦谈多话 2021-02-04 09:03

So I have a list from which I obtain a parallel stream to fill out a map, as follows:

Map map = new HashMap<>();
List

        
3条回答
  •  -上瘾入骨i
    2021-02-04 09:30

    With this list.parallelStream().forEach you are violating the side-effects property that is explicitly stated in the Stream documentation.

    Also when you say this code is that the map is being printed out when the "putting data" process is still going on (cuz it's parallel), this is not true, as forEach is a terminal operation and it will wait to be finished, until it can go an process the next line. You might be seeing that as such, since you are collecting to a non thread-safe HashMap and some entries might not be in that map... Think about about other way, what would happen if you would put multiple entries from multiple threads in a HashMap? Well, lots of things can break, like missing entries, on incorrect/inconsistent Map, etc.

    Of course, changing that to a ConcurrentHashMap would work, since it's thread-safe, but you are still violating the side-effect property, although in a "safe" way.

    The correct thing to do is to collect to a Map directly without forEach:

    Map map = list.parallelStream()
            .collect(Collectors.toMap(
                    NodeData::getId,
                    TreeNode::new
            ));
    

    This way, even for parallel processing, everything would be fine. Just notice that you would need lots (tens of thousands elements) to have any measurable performance increase from parallel processing.

提交回复
热议问题