Question

I know that spinning off threads in a JavaEE application is a big no-no. However, I have an application that is a perfect candidate for Java's fork/join mechanism. But, since threads are not supposed to be created within an application, is there any way to make use of this within my EJB? I know that on WebSphere applications the async bean functionality provides this. However, my application is deployed on JBoss EAP 6.1, so this is not an option.

Is there a "legal" way to accomplish fork/join within a JavaEE application?

Was it helpful?

Solution

The best answer now is the Concurrency Utils API in the Java EE 7 specification. You have ManagedExecutors and ManagedThreadPools. Since these managed threads features are and managed tasks are controlled by the application server then ensure your fork join computation uses these resources then you can ensure that threads are contained and not orphaned.

Finally you probably have to write a version of ForkJoinPool that is 'Managed' to get the optimal solution. However it should be possible because one would replace the thread pool executor with the managed version as a first step.

PS: Java EE 8 must resolve this when Java SE 8 is released!

OTHER TIPS

JBoss EAP 6.1 actually supports async EJBs as well. But AFAIK async EJBs only really help you when you don't need to wait for the results of the subtasks (eg. you only need the fork part, not the join part).

If you use java.util.concurrent.ForkJoinPool there isn't a legal way of using it in Java EE and Java EE 7 / JSR-236 does not help (I raised this point with the EG but they couldn't be bothered). ForkJoinPool spwans threads which is illegal and ManagedThreadFactory from EE 7 / JSR-236 is not a ForkJoinWorkerThreadFactory.

In JDK 8 there is a default ForkJoinPool which can be configured to not spawn any threads and run everything in the caller thread (probably through the "java.util.concurrent.ForkJoinPool.common.parallelism" system property). This makes it legal but won't give you any parallelism.

On a more general note fork join tasks should be compute bound and not IO bound. In theory spawning thread threads in Java EE is safe as long as you don't use any Java EE features (and let them terminate when your application undeploys). For example:

  • transactions
  • JDBC
  • JPA (including lazy loading)
  • security
  • EJBs
  • remoting
  • class loading
  • JNDI

These features also generally make tasks IO bound instead of CPU bound.

And yes the same issues apply to JDK 8 parallel streams.

You can create a Singleton ejb, which is similar to a "service" (i.e. a JMX service). within the context of this special service, you can control threading and synchronization. so, you can create a singleton ejb which encapsulates the job execution with the fork/join logic, and your standard ejbs/mdbs can utilize this service.

In JavaEE the container controls the threads. Just imagine what would happen if every programmer decided to create his own threads? In any case the use of threads in the parallel bulk operations for Java8 have been rejected. SEE HERE You can make any assumption you want, yes I wrote the article.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top