So, I'm trying to get my head around the Stream API introduced in Java 8. I'm trying to make a stream that can run on a separate thread (just for educational purposes)
String oracle = "http://www.oracle.com";
URL url = new URL(oracle);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
in.lines().parallel().forEach(System.out::println);
System.out.print("CLOSING THE INPUT STREAM!, shouldnt this crash?");
in.close();
The outcome is not what I would expect.. (I was expecting a crash, since I closed the input stream while the other thread is reading from it). Note the .parallel()
method call. Instead the code seems to be executing in a sequential manner with no problems.
OUTPUT:
<script language="JavaScript" src="http://www.oracleimg.com/us/assets/metrics/ora_ocom_hp.js"></script>
<!-- End SiteCatalyst code -->
<!-- SS_END_SNIPPET(fragment6,1)-->
<!-- SS_BEGIN_SNIPPET(fragment7,ui)--> <!-- SS_END_SNIPPET(fragment7,ui)-->
</html>
CLOSING THE INPUT STREAM!, shouldnt this crash?
Does anyone know what's going on? Why is my code not crashing?
Meanwhile, in the case of a parallel stream, two threads are spawned simultaneously, and the stream internally uses ForkJoinPool to create and manage threads. Parallel streams create a ForkJoinPool instance via the static ForkJoinPool. commonPool() method.
Normally any java code has one stream of processing, where it is executed sequentially. Whereas by using parallel streams, we can divide the code into multiple streams that are executed in parallel on separate cores and the final result is the combination of the individual outcomes.
A Java Parallel stream uses the fork-join framework and its common pool of worker threads to perform parallel executions.
Parallel Stream The default processing that occurs in such a Stream uses the ForkJoinPool. commonPool(), a thread pool shared by the entire application.
The parallel stream will indeed attempt splitting the work of reading the lines to mutiple threads. But the invocation itself is blocking, i.e. the statement waits until all threads finished to proceed to the next statement (where you close the input stream).
One thing to note is that forEach
does not guarantee that the parallel actions execute in the same order of the stream elements, so the printed lines in this case may not be in the same order with the original Web page (see https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#forEach-java.util.function.Consumer-).
If you want to execute things in the background without immediately blocking for their completion you can use java.util.concurrent.CompletableFuture.runAsync(Runnable)
and related methods. It returns a CompletableFuture which can be joined later if needed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With