X

Concurrency Utilities for Java EE Early Draft (JSR 236)



Concurrency Utilities for Java EE is being worked as href="http://jcp.org/en/jsr/detail?id=236">JSR 236 and has
released an href="http://jcp.org/aboutJava/communityprocess/edr/jsr236/index.html">Early
Draft. It provides concurrency capabilities to Java EE
application components without compromising container integrity.
Simple (common) and advanced concurrency patterns are easily
supported without sacrificing usability.



Using Java SE concurrency utilities such as java.util.concurrent
API, java.lang.Thread and java.util.Timer
in a Java EE application component such as EJB or Servlet are
problematic since the container and server have no knowledge of
these resources. The JSR 236 enables concurrency largely by
extending the Concurrency Utilities API developed under JSR-166.
This also allows a consistency between Java SE and Java EE
concurrency programming model. The threads so spawned are provided
and managed by the container.



There are four main programming interfaces available:
  • ManagedExecutorService
  • ManagedScheduledExecutorService
  • ContextService
  • ManagedThreadFactory

ManagedExecutorService is a managed version of java.util.concurrent.ExecutorService.
The implementations of this interface are provided by the
container and accessible using JNDI reference:

<resource-env-ref>
  <resource-env-ref-name>
    concurrent/BatchExecutor
  </resource-env-ref-name>
  <resource-env-ref-type>
    javax.enterprise.concurrent.ManagedExecutorService
  </resource-env-ref-type>
<resource-env-ref>

and available as:

@Resource(name="concurrent/BatchExecutor")
ManagedExecutorService executor;

Its recommended to bind the JNDI references in the java:comp/env/concurrent
subcontext.



The asynchronous tasks that need to be executed need to implement
java.lang.Runnable or java.util.concurrent.Callable
interface as:

public class MyTask implements Runnable {
public void run() {
// business logic goes here
}
}

OR

public class MyTask2 implements Callable<Date> {
  public Date call() {
// business logic goes here
  }
}

The task is then submitted to the executor using one of the submit
method that return a Future instance. The Future
represents the result of the task and can also be used to check if
the task is complete or wait for its completion.

Future<String> future = executor.submit(new MyTask(), String.class);
. . .
String result = future.get();

The task would run on a separate thread provided and managed by
the container.

Another example to submit tasks is:

class MyTask implements Callable<Long> { . . . }
class MyTask2 implements Callable<Date> { . . . }

ArrayList<Callable> tasks = new ArrayList<();
tasks.add(new MyTask());
tasks.add(new MyTask2());
List<Future<Object>> result = executor.invokeAll(tasks);

The ManagedExecutorService may be configured for
different properties such as:

  • Hung Task Threshold: Time in milliseconds that a task
    can execute before it is considered hung
  • Pool Info
    • Core Size: Number of threads to keep alive
    • Maximum Size: Maximum number of threads allowed in
      the pool
    • Keep Alive: Time to allow threads to remain idle when
      # of threads > Core Size
    • Work Queue Capacity: # of tasks that can be stored in
      inbound buffer

  • Thread Use: Application intend to run short vs
    long-running tasks, accordingly pooled or daemon threads are
    picked

The specification does not mandate any configuration attributes.
The above mentioned properties are only examples and may not be
supported by all application servers.

    ManagedScheduledExecutorService adds delay and
    periodic task running capabilities to ManagedExecutorService.
    The implementations of this interface are provided by the
    container and accessible using JNDI reference:

    <resource-env-ref>
      <resource-env-ref-name>
        concurrent/BatchExecutor
      </resource-env-ref-name>
      <resource-env-ref-type>
        javax.enterprise.concurrent.ManagedExecutorService
      </resource-env-ref-type>
    <resource-env-ref>

    and available as:

    @Resource(name="concurrent/timedExecutor")
    ManagedExecutorService executor;

    And then the tasks are submitted using submit, invokeXXX
    or scheduleXXX methods.

    ScheduledFuture<?> future = executor.schedule(new MyTask(), 5, TimeUnit.SECONDS);

    This will create and execute a one-shot action that becomes
    enabled after 5 seconds of delay.

    More control is possible using one of the newly added methods:

    MyTaskListener implements ManagedTaskListener {
      public void taskStarting(...) { . . . }
      public void taskSubmitted(...) { . . . }
      public void taskDone(...) { . . . }
      public void taskAborted(...) { . . . }
    }
    ScheduledFuture<?> future =
    executor.schedule(new MyTask(),
    5,
    TimeUnit.SECONDS,
    new MyTaskListener());

    Here, ManagedTaskListener is used to monitor the
    state of a task's future.

    ManagedThreadFactory provides a method for creating
    threads for execution in a managed environment. A simple usage is:

    @Resource(name="concurrent/myThreadFactory")
    ManagedThreadFactory factory;
    . . .
    Thread thread = factory.newThread(new Runnable() { . . . });

    concurrent/myThreadFactory is a JNDI resource.

    There is lot of interesting content in the href="http://jcp.org/aboutJava/communityprocess/edr/jsr236/index.html">Early
    Draft, download it, and read yourself. The implementation
    will be made available soon and also be integrated in GlassFish 4
    as well.

    Some references for further exploration ...

    • Javadoc
    • href="http://jcp.org/aboutJava/communityprocess/edr/jsr236/index.html">Early
      Draft Specification

    • concurrency-ee-spec.java.net
    • href="http://java.net/projects/concurrency-ee-spec/lists/users/archive">users@concurrency-ee-spec.java.net

    Join the discussion

    Comments ( 4 )
    • Hanine Wednesday, December 5, 2012

      Interesting. I guess this would indeed benefit Java EE 7 in the cloud.


    • Oded Shopen Thursday, December 6, 2012

      This sounds a lot like things that were available ever since J2EE 1.4 with some queue configuration. I remember developing a framework for Weblogic 8.1 for parallel task execution using a non-persistent JMS queue and dynamic temporary queues (part of the API), which is still working with great performance in production environments. Add to it the timer API and you get all the features here. So the only benefit is really perhaps a simpler and more direct threading API.


    • Shobhit Wednesday, January 23, 2013

      Is there any server available that have implemented this JSR-236?


    • Arun Gupta Wednesday, January 23, 2013

      Shobhit,

      GlassFish 4 is the only server that is implementing JSR 236 at this time. A basic integration work has been done but the JNDI name resolution is still not working. I'll blog about it once that is ready.


    Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha
    Oracle

    Integrated Cloud Applications & Platform Services