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?
-
The restrictions pertain to transparent distribution of components across multiple application servers. It is not correct (but should be safe) to break the JEE component contract IFF the feature set e.g. transparent distribution is not a concern. – alphazero Apr 03 '14 at 18:20
-
@RobertHarvey You should probably reopen. – assylias Apr 03 '14 at 20:41
-
"Would it be an issue?" That's not even a question. – Robert Harvey Apr 03 '14 at 20:42
-
3@RobertHarvey using threads in JavaEE is dicouraged - Java 8 introduces parallel streams (which use threads in the background). Can we use parallel streams in JavaEE or is it discouraged too? I think that is a fair and interesting question. I have rephrased a bit - it can probably be improved further. – assylias Apr 03 '14 at 20:46
-
Primarily opinion-based. Couldn't the question at least have framed itself by restating the *reasons* why spawning threads in Java EE containers are discouraged, and then asking how those reasons are addressed in Java EE? It might be too broad, but at least it's an actual question. – Robert Harvey Apr 03 '14 at 20:50
-
3@RobertHarvey ? Threads are discouraged (or even forbidden by some specs) because threads are meant to be managed by the application server itself (see first link on the right) - using parallel streams may "break stuff" - or not. And that is the question. Either it may or it may not "break stuff" based on specs: that is not an opinion. Just my 2 cts. Your call - I'm off for the day! ;-) (and feel free to delete the noise after making your decision) – assylias Apr 03 '14 at 20:56
-
Following the argument of assylias, we would like to understand the relation between parallel streams with J2EE containers, would that "break stuff"? – Luís Bianchin Apr 03 '14 at 21:04
-
14Yes, it would break stuff. The security and transactional context are handled by ThreadLocal variables, for example. And JPA entities aren't thread-safe. So spawning threads, whatever the way you spawn them, will break the security and transactional handling. The Java EE 7 specification introduces special executors that are supposed to be used if you want to execute tasks in threads in a Java EE environment. But Java EE is lagging behind Java SE, and is not ready for parallel streams yet. – JB Nizet Apr 03 '14 at 21:32
-
2Its a good question and has been answered by the Java EE engineers. They revert to sequential processing for all parallel operations. You can find the discussion on the lambda-dev@openjdk.java.net mailing list. – edharned Apr 04 '14 at 18:46
-
1Definitely a question that I could use the answer to. Can anyone provide a link for the discussion @edharned mentioned? Google's not showing much. – Shorn Apr 07 '14 at 05:21
-
3@Shorn: http://mail.openjdk.java.net/pipermail/lambda-dev/2013-April/009334.html – JB Nizet Apr 07 '14 at 18:52
2 Answers
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.
-
Couldn't gracefully degradation be achieved in a portable way by setting the `java.util.concurrent.ForkJoinPool.common.parallelism` system property to `1`? – areus Jan 08 '21 at 12:03
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?

- 19,077
- 15
- 90
- 168
-
1Graceful degradation of parallel stream processing to single threaded isn't yet part of Java EE Concurrency. So it's still unsafe to use parallel streams in Java EE 8. There are plans to address it in the future within Jakarta EE Concurrency: https://github.com/eclipse-ee4j/concurrency-api/issues/46 – OndroMih May 05 '20 at 10:20