Java and Competition:
- Java has always been at the forefront of facilitating concurrent programming, offering native thread support since 1996 and evolving to include libraries such as java.util.concurrent and the fork-join framework.
Streams and Parallelism:
- With the introduction of streams in Java 8, it became easy to parallelize operations with a single call to the parallel() method. However, even with the ease, writing correct and fast concurrent programs remains challenging.
Performance and Failures:
- Careless parallelization of stream pipelines can lead to performance and liveness failures (programs that do not finish). An example given shows that parallelizing a stream can result in a significant increase in CPU usage without visible results.
Heuristics and Limitations:
- Stream parallelization can fail if the heuristics used to divide the work are not suitable, especially in operations like Stream.iterate and limit, where the costs of calculating extra elements can be very high.
Ideal Data Structures:
Streams over ArrayList, HashMap, HashSet, ConcurrentHashMap, arrays and ranges are better candidates for parallelization due to the ease of dividing work between threads and good locality of reference.
Terminal Operations:
- The effectiveness of parallel execution also depends on the terminal operation of the stream. Reduction operations such as reduce, min, max, count, and sum, and short-circuit operations such as anyMatch, allMatch, and noneMatch are best for parallelism.
Strict Specifications:
- Functions used in parallel pipelines must be associative, non-interfering and stateless. Violation of these rules may cause incorrect results or catastrophic failures.
Execution Orders:
- Parallelizing a pipeline can clutter the output, and operations like forEachOrdered may be necessary to preserve order.
Justified Parallelism:
- Parallelize a stream only if there is a solid justification. Inadequate parallelism can result in crashes or poor performance. Always measure performance before and after parallelization to ensure it is beneficial.
Example of Effectiveness:
- A simple example showed that parallelizing a π(n) calculation reduced the execution time from 31 to 9.2 seconds, demonstrating that parallelism can be efficient in certain scenarios.
Use of SplittableRandom:
- For parallel random number streams, prefer SplittableRandom over ThreadLocalRandom or Random as it is specifically designed for this use and offers better performance.
Conclusion:
- Do not attempt to parallelize a stream pipeline without having a good reason to believe that doing so will preserve calculation accuracy and increase speed. Conduct rigorous testing to verify that parallelism is justified before applying it to production code.
EXAMPLES
1. Sequential vs. Sequential Stream Example Parallel
- This example demonstrates the difference in performance between a sequential and a parallel stream. ParallelStreamExample.java
2. Example of Inefficient Use of parallel()
- This example shows how parallelization can lead to unexpected behavior. InefficientParallelStream.java
3. Example of Efficient Use of parallel()
- This example shows a situation where parallelization can actually improve performance. EfficientParallelStream,java
4. Example of Security Flaws with Parallel Streams
- This example demonstrates how a poorly implemented reduce operation can fail when used in parallel. ParallelStreamSafetyExample.java
5. Example with SplittableRandom for Parallel Streams
- This example demonstrates the use of SplittableRandom in a parallel stream for better performance. SplittableRandomExample.java
These examples help illustrate situations where parallelization can be useful and also show the potential risks of using parallel() indiscriminately.
The above is the detailed content of Item Be careful when doing parallel streams. For more information, please follow other related articles on the PHP Chinese website!