Java 8 Parallel Stream Examples

Table of Contents

  1. Sequential Stream Example
  2. Parallel Stream Example
  3. Custom Thread Pool Example
  4. Performance Comparison

1. Sequential Stream Example

This example demonstrates finding prime numbers using a sequential stream in Java. It showcases the basic implementation of the prime number algorithm and measures the execution time.

The parallel stream example follows, illustrating how to leverage multi-core processors for improved performance in prime number calculation. Both examples provide a foundation for understanding stream processing in Java.

2. Parallel Stream Example


    import java.util.stream.IntStream;

    public class ParallelPrimeNumberFinder {
        public static boolean isPrime(int number) {
            return number > 1 && IntStream.rangeClosed(2, (int) Math.sqrt(number))
                    .noneMatch(i -> number % i == 0);
        }

        public static void main(String[] args) {
            long startTime = System.currentTimeMillis();
            long primeCount = IntStream.range(2, 100000)
                    .parallel()
                    .filter(ParallelPrimeNumberFinder::isPrime)
                    .count();
            long endTime = System.currentTimeMillis();

            System.out.println("Number of primes: " + primeCount);
            System.out.println("Time taken: " + (endTime - startTime) + " ms");
        }
    }
    

3. Custom Thread Pool Example

This example demonstrates using a custom thread pool for parallel prime number calculation. It allows fine-tuning of thread allocation for optimal performance on different hardware configurations.


    import java.util.concurrent.ForkJoinPool;
    import java.util.stream.IntStream;

    public class CustomPoolPrimeNumberFinder {
        public static boolean isPrime(int number) {
            return number > 1 && IntStream.rangeClosed(2, (int) Math.sqrt(number))
                    .noneMatch(i -> number % i == 0);
        }

        public static void main(String[] args) {
            int parallelism = Runtime.getRuntime().availableProcessors();
            ForkJoinPool customThreadPool = new ForkJoinPool(parallelism);

            long startTime = System.currentTimeMillis();
            long primeCount = customThreadPool.submit(() ->
                IntStream.range(2, 100000)
                        .parallel()
                        .filter(CustomPoolPrimeNumberFinder::isPrime)
                        .count()
            ).join();
            long endTime = System.currentTimeMillis();

            System.out.println("Number of primes: " + primeCount);
            System.out.println("Time taken: " + (endTime - startTime) + " ms");
            customThreadPool.shutdown();
        }
    }
    

The performance comparison section that follows compares the execution times of sequential, parallel, and custom thread pool approaches. This comparison helps in understanding the efficiency gains of different parallelization strategies.

4. Performance Comparison


    import java.util.concurrent.ForkJoinPool;
    import java.util.stream.IntStream;

    public class PrimeNumberPerformanceComparison {
        public static boolean isPrime(int number) {
            return number > 1 && IntStream.rangeClosed(2, (int) Math.sqrt(number))
                    .noneMatch(i -> number % i == 0);
        }

        public static long countPrimesSequential() {
            return IntStream.range(2, 1000000)
                    .filter(PrimeNumberPerformanceComparison::isPrime)
                    .count();
        }

        public static long countPrimesParallel() {
            return IntStream.range(2, 1000000)
                    .parallel()
                    .filter(PrimeNumberPerformanceComparison::isPrime)
                    .count();
        }

        public static long countPrimesCustomPool() {
            int parallelism = Runtime.getRuntime().availableProcessors();
            ForkJoinPool customThreadPool = new ForkJoinPool(parallelism);

            return customThreadPool.submit(() ->
                IntStream.range(2, 1000000)
                        .parallel()
                        .filter(PrimeNumberPerformanceComparison::isPrime)
                        .count()
            ).join();
        }

        public static void main(String[] args) {
            long startTime, endTime;

            startTime = System.currentTimeMillis();
            long sequentialCount = countPrimesSequential();
            endTime = System.currentTimeMillis();
            System.out.println("Sequential - Count: " + sequentialCount + ", Time: " + (endTime - startTime) + " ms");

            startTime = System.currentTimeMillis();
            long parallelCount = countPrimesParallel();
            endTime = System.currentTimeMillis();
            System.out.println("Parallel - Count: " + parallelCount + ", Time: " + (endTime - startTime) + " ms");

            startTime = System.currentTimeMillis();
            long customPoolCount = countPrimesCustomPool();
            endTime = System.currentTimeMillis();
            System.out.println("Custom Pool - Count: " + customPoolCount + ", Time: " + (endTime - startTime) + " ms");
        }
    }
    

Comments & Discussion

Facing issues? Have questions? Post them here! We're happy to help!