package com.oracle.java.corelibs;

import java.util.; 
import java.util.concurrent.; 
import java.util.concurrent.locks.; 
import java.util.stream.; 

 
  Both Arrays.parallelSort() and Stream.parallel().sorted() 
  get stuck when all the forkjoin threads in the common pool 
  are currently blocked. 
  p 
  We start by grabbing a thread from the common fork join pool 
  (we'll use that later). 
  p 
  Park all threads in common pool, in addition to the thread 
  that submitted the task (see nasty thread). 
  p 
  We then generate random numbers in parallel (this works). 
  p 
  We submit 4 jobs to the pool to be executed concurrently. We 
  are able to sort sequentially, but not in parallel. Only when 
  we unpark the thread we grabbed earlier from the common FJPool 
  thread. Now the parallel sorting returns again. 
  
public class ParallelSortBug2 { 
  public static void main(String... args) throws Exception { 
    Thread someFJThread = ForkJoinPool.commonPool().submit( 
        ThreadcurrentThread).get(); 

    System.out.println(someFJThread =  + someFJThread); 

    new Thread(nasty) { 
      { setDaemon(true);} 

      @Override
      public void run() { 
        IntStream.range(0, Runtime.getRuntime().availableProcessors()) 
            .parallel().forEach(i1 - LockSupport.park()); 
      } 
    }.start(); 

    Thread.sleep(100); 

     we can still generate our random array in parallel 
    int[] numbers = ThreadLocalRandom.current().ints(10_000_000) 
        .parallel().toArray(); 

    ExecutorService pool = Executors.newCachedThreadPool(); 

    pool.submit(() - { 
      System.out.println(sortingParallelWithStreams start); 
      System.out.println(IntStream.of(numbers.clone()). 
          parallel().sorted().summaryStatistics()); 
      System.out.println(sortingParallelWithStreams done); 
    }); 

    pool.submit(() - { 
      System.out.println(sortingSequentialWithStreams start); 
      System.out.println(IntStream.of(numbers.clone()). 
          sorted().summaryStatistics()); 
      System.out.println(sortingSequentialWithStreams done); 
    }); 

    pool.submit(() - { 
      System.out.println(sortingParallelWithArrays start); 
      int[] toSort = numbers.clone(); 
      Arrays.parallelSort(toSort); 
      System.out.println(toSort[204]); 
      System.out.println(sortingParallelWithArrays done); 
    }); 

    pool.submit(() - { 
      System.out.println(sortingSequentialWithArrays start); 
      int[] toSort = numbers.clone(); 
      Arrays.sort(toSort); 
      System.out.println(toSort[204]); 
      System.out.println(sortingSequentialWithArrays done); 
    }); 


    pool.shutdown(); 

    for (int i = 0; i  10 && !pool.awaitTermination(1, TimeUnit.SECONDS); i++) { 
      System.out.println(Waiting for the threads to finish); 
    } 

    System.out.println(Unparking one FJ thread); 
    LockSupport.unpark(someFJThread); 

    while (!pool.awaitTermination(1, TimeUnit.SECONDS)) { 
      System.out.println( ... Waiting for the threads to finish); 
    } 

    System.out.println(All done!); 
  } 
} 