Given that spawning threads in Java EE containers are discouraged. Would using the Java 8 parallel streams, which may spawn threads, inside Java EE be discouraged too?
1. Parallel Streams can actually slow you down. Java 8 brings the promise of parallelism as one of the most anticipated new features.
Parallel streams divide the provided task into many and run them in different threads, utilizing multiple cores of the computer. On the other hand sequential streams work just like for-loop using a single core.
Java 8 introduces the concept of the parallel stream to do parallel processing. As we have a number of CPU cores nowadays due to cheap hardware costs, parallel processing can be used to perform operation faster. If you notice the output, the main thread is doing all the work in case of the sequential stream.
A heads up, the graceful degradation to single thread is not available. I also thought it was because of Shorn's answer and that mailing list discussion, but I found out it wasn't while researching for this question. The mechanism is not in the Java EE 7 spec and it's not in glassfish 4.1. Even if another container does it, it won't be portable.
You can test this by calling the following method:
@Singleton public class SomeSingleton { public void fireStream() { IntStream.range(0, 32) .parallel() .mapToObj(i -> String.format("Task %d on thread %s", i, Thread.currentThread().getName())) .forEach(System.out::println); } }
And you'll get something like:
Info: Task 20 on thread http-listener-1(4) Info: Task 10 on thread ForkJoinPool.commonPool-worker-3 Info: Task 28 on thread ForkJoinPool.commonPool-worker-0 ...
I've also checked glassfish 4.1.1 source code, and there isn't a single use of ForkJoinPool
, ForkJoinWorkerThreadFactory
or ForkJoinWorkerThread
.
The mechanism could be added to EE 8, since many frameworks will leverage jdk8 features, but I don't know if it's part of the spec.
EDIT See alternate answer from andrepnh
. The below may have been the plan, but it doesn't appear to have played out that way in practice.
The way I read it from the lambda-dev mailing list discussion mentioned in the comments: it's not discouraged the way spawning threads is - but won't do anything much for you in a Java EE context.
From the linked discussion:
the Java EE concurrency folks had been already talked through this, and the current outcome is that FJP will gracefully degrade to single-threaded (even caller-context) execution when running from within the EE container
So you're able to safely use parallel streams in a procedure or library that runs in both contexts. When it's run in a SE environment, it will make with the magical parallel shenanigans - but when it's run in an EE environment it will gracefully degrade to serial execution.
Note: the phrase quoted above is future tense - does anyone have a citation for some definitive documentation?
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