1 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. JSR 236: Concurrency Utilities for Java EE Applications Shing Wai Chan (陳成威) Anissa Lam (梁鈺儀) Session ID: CON1468 The preceding is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle. 3 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Program Agenda Overview Managed Objects Context & Transaction Summary Resources 4 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Overview New to Java EE 7 Simple, standardized API for using concurrency from application components Extension of Java SE Concurrency Utilities APIs (JSR-166) Low-level asynchronous processing capabilities to Java EE application components in a safe, reliable, consistent manner Manage and monitor the lifecycle of asynchronous operations 5 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Overview Provides 4 types of managed objects that implement these interfaces – ManagedExecutorService – ManagedScheduledExecutorService – ManagedThreadFactory – ContextService Context propagation Transaction Management 6 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Overview Managed Objects are provided by the Java EE Product Provider Pre-configured default object is available Applications look up managed objects by – JNDI lookup – resource injection using @Resource 7 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Program Agenda Overview Managed Objects Context & Transaction Summary Resources 8 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedExecutorService Overview For running tasks asynchronously on threads provided by Java EE product provider Container context captured from submitting thread to be applied on execution thread Not transactional – tasks should use their own transactions Preconfigured default: – java:comp/DefaultManagedExecutorService 9 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedExecutorService API Extends from java.util.concurrent.ExecutorService – execute, submit, invokeAll, invokeAny – No new APIs Lifecycle APIs disabled – throws IllegalStateException awaitTermination, isTerminated, isShutdown, shutdown, shutdownNow Future is returned upon task submission – check for the execution status – cancel the task – Wait and retrieve result 10 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedExecutorService API void execute(Runnable command); <T> Future<T> submit(Callable<T> task); Future<?> submit(Runnable task); <T> Future<T> submit(Runnable task, T result); <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks); <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit); <T> T invokeAny(Collection<? extends Callable<T>> tasks) <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit); 11 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedExecutorService Example #1 @Resource(name=“concurrent/myExecutor”) ManagedExecutorService mes; void someMethod() { Callable<Integer> c = new Callable<>() { Integer call() { // Interact with a database...return answer. } //Submit the task and do something else. Future result = mes.submit(c); ... //Get the result when ready... int theValue = result.get(); ... 12 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedExecutorService Example #2 // Retrieve all accounts from several account databases in parallel. //JNDI Lookup javax.naming.InitialContext ctx = new InitialContext(); ManagedExecutorService mes = (ManagedExecutorService) ctx.lookup("java:comp/DefaultManagedExecutorService"); // Create a set of tasks to perform the account retrieval. ArrayList<Callable<Account>> retrieverTasks = new ArrayList<Callable<Account>>(); retrieverTasks.add(new EISAccountRetriever()); retrieverTasks.add(new RDBAccountRetriever()); // Submit the tasks to the thread pool and wait for completion. List<Future<Account>> taskResults= mes.invokeAll(retrieverTasks); 13 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedExecutorService Example #2 (cont’d) // Retrieve the results from the resulting Future list. ArrayList<Account> results = new ArrayList<Account>(); for(Future<Account> taskResult : taskResults) { try { results.add(taskResult.get()); } catch (ExecutionException e) { Throwable cause = e.getCause(); } } return results; public class EISAccountRetriever implements Callable<Account> { public Account call() { … } } 14 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedExecutorService Configuration Choose a more simplistic approach add more functionality such as Quality-of-service, Persistence or Task partitioning etc. Possible options: (as in GlassFish 4.0) – JNDI Name – Context Info – Thread Priority – Hung Task Threshold 15 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedExecutorService Configuration (cont’d) Configuration of the underlying thread pool. – Core size – Maximum Pool Size – Thread Lifetime – Keep Alive – Task Queue Capacity Cached thread pool as described in java.util.concurrent.Executors will be created when no attribute is specified. 16 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedExecutorService Managed Thread Pool Executor Component Relationship 17 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedScheduledExecutorService Overview For scheduling tasks to run on threads – after a given delay, – run periodically – at some custom schedule tasks are also run on threads that are provided by the Java EE container. Preconfigured default: java:comp/DefaultManagedScheduledExecutorService 18 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedScheduledExecutorService API Extends from – ManagedExecutorService – java.util.concurrent.ScheduledExecutorService APIs in addition to ManagedExecutorService – schedule – scheduleAtFixedRate – scheduleWithFixedDelay Extension API to support custom scheduling – schedule with Trigger 19 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedScheduledExecutorService API <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit); ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit); ScheduledFuture<?> scheduleAtFixedFate(Runnable command, long initialDelay, long period, TimeUnit unit); ScheduledFuture<?> scheduledWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit); ScheduledFuture<?> schedule(Runnable command, Trigger trigger); <V> ScheduledFuture<V> schedule(Callable<V> callable, Trigger trigger); 20 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedScheduledExecutorService Configuration In GlassFish 4.0, same configuration as in ManagedExecutorService except for – Task Queue Capacity – Maximum Pool Size Reason: a fixed-size pool with an unbounded queue are always used in ManagedScheduledExecutorService. 21 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedScheduledExecutorService Trigger Allows application developer to plugin rules for running a task. Can be simple: single, absolute date-time Can include Java™ EE business calendar logic Registered with a task when it is submitted Invoked within the same process in which it was registered. 22 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedScheduledExecutorService Trigger API boolean skipRun(LastExecution lastExecutionInfo, Date scheduledRunTime) Date getNextRunTime(LastExecution lastExecutionInfo, Date taskScheduledTime) 23 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedScheduledExecutorService Trigger Example public class SingleDateTrigger implements Trigger { private Date fireTime; public TriggerSingleDate(Date newDate) { fireTime = newDate; } public Date getNextRunTime( LastExecution lastExecutionInfo, Date taskScheduledTime) { if(taskScheduledTime.after(fireTime)) { return null; } return fireTime; } public boolean skipRun(LastExecution lastExecutionInfo, Date scheduledRunTime) { return scheduledRunTime.after(fireTime); } } 24 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedExecutors Utilities for classes defined in javax.enterprise.concurrent Tests if current thread is a ManageableThread Tests if current thread has been marked for shutdown #managedTask – Returns a Callable/Runnable that also implements ManagedTask 25 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedExecutors API public static boolean isCurrentThreadShutdown() public static Runnable managedTask(Runnable task, ManagedTaskListener taskListener) throws IllegalArgumentException public static Runnable managedTask(Runnable task, Map<String,String> executionProperties, ManagedTaskListener taskListener) throws IllegalArgumentException public static <V> Callable<V> managedTask(Callable<V> task, ManagedTaskListener taskListener) throws IllegalArgumentException public static <V> Callable<V> managedTask(Callable<V> task, Map<String,String> executionProperties, ManagedTaskListener taskListener) throws IllegalArgumentException 26 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Managed[Scheduled]ExecutorService ManagedTask Any task submitted to an Managed[Scheduled]ExecutorService can optionally implement ManagedTask Provides – Identifying information – ManagedTaskListener for lifecycle events notification – Additional execution properties 27 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Managed[Scheduled]ExecutorService ManagedTask API – Map<String, String> getExecutionProperties() – ManagedTaskListener getManagedTaskListener() Execution properties – LONGRUNNING_HINT – IDENTITY_NAME – TRANSACTION SUSPEND USE_TRANSACTION_OF_EXECUTION_THREAD 28 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Managed[Scheduled]ExecutorService ManagedTaskListener Monitor the state of a task’s Future Registered with a ManagedExecutorService using submit Invoked when the state of Future changes Each instance is invoked within same process that the listener was registered 29 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Managed[Scheduled]ExecutorService ManagedTaskListener API void taskSubmitted(Future<?> future, ManagedExecutorService executor, Object task) void taskDone(Future<?> future, ManagedExecutorService executor, Object task, Throwable exception) void taskStarting(Future<?> future, ManagedExecutorService executor, Object task) void taskSubmitted(Future<?> future, ManagedExecutorService executor, Object task) 30 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Managed[Scheduled]ExecutorService Example: Registering ManagedTaskListener // Runnable implements ManagedTask public class TaskWithListener implements Runnable, ManagedTask { ... public ManagedTaskListener getManagedTaskListener() { return aManagedTaskListener; } } //use ManagedExecutors utility to associate a ManagedTaskListener to a task Runnable aTask; ManagedTaskListener myTaskListner; Runnable taskWithListener = ManagedExecutors.managedTask(aTask, myTaskListener); ... ManagedExecutorService executor = ...; executor.submit(task); 31 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedThreadFactory Overview A standard way for applications to obtain a container-managed threads from Java EE Container Container context captured at newThread call to be applied to thread that invokes r.run() For creating custom executors in advanced use cases Preconfigured default: – java:comp/DefaultManagedThreadFactory 32 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedThreadFactory Sample Configuration JNDI Name Context Info – Classloader – JNDI – Security Priority 33 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedThreadFactory API Interface extends from java.util.concurrent.ThreadFactory – Same API: Thread newThread(Runnable) Threads returned by newThread() method must implement the ManagableThread interface – boolean isShutdown() Can be used with Java SE concurrency utilities APIs where ThreadFactory is needed. e.g. in java.util.concurrent.Executors 34 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedThreadFactory Shutdown Thread interrupted when ManagedThreadFactory shuts down Runnable should check ManagableThread.isShutdown() when interrupted, and clean up if it is true. 35 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedThreadFactory Example 1 // Create a ThreadPoolExecutor using a ManagedThreadFactory. @Resource(lookup=“java:comp/DefaultThreadFactory”) ManagedThreadFactory tf; public ExecutorService getManagedThreadPool() { // All threads will run as part of this application component. return new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10), tf); } 36 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ManagedThreadFactory Example 2 (with Servlet Asynchronous mode) public class TestServlet extends HttpServlet { @Resource(lookup=“java:comp/DefaultManagedFactory”) private ManagedThreadFactory managedThreadFactory; protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { final AsyncContext asyncContext = req.startAsync(); … Runnable runnable = new Runnable() { public void run() { … asyncContext.complete(); } }; Thread thread = managedThreadFactory.newThread(runnable); thread.start(); } 37 } Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ContextService Overview For creating contextual proxy objects to capture container context to be run within the captured context at a later time For use in advanced use cases such as to propagate user identity or to request task listener notifications to be run under container context Contextual proxy objects can also be used as tasks for submission to Managed[Scheduled]ExecutorService or ManagedThreadFactory Preconfigured default: – java:comp/DefaultContextService 38 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ContextService Sample Configuration JNDI Name Context Info – Classloader – JNDI – Security 39 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ContextService API Interface Creating dynamic proxy (as in java.lang.reflect.Proxy) With additional context such as class loading, namespace, security, etc. The instance must implement Serializable if the proxy is serialized Execution properties, Map<String, String> – reserved keys: started with “javax.enterprise.concurrent.” – E.g. vendor.security.tokenexpiration 40 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ContextService API (cont’d) Four createContextualProxy methods: – <T> T createContextualProxy(T instance, Class<T> intf) – <T> T createContextualProxy(T instance, Map<String,String> executionProperties, Class<T> intf) – Object createContextualProxy(Object instance, Map<String,String> executionProperties, Class<?>... Interfaces) – Object createContextualProxy(Object instance, Class<?>... Interfaces) 41 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ContextService API (cont’d 2) For returning the execution properties on the given contextual object proxy instance – Map<String,String> getExecutionProperties(Object contextualProxy) – IllegalArgumentException: if contextualProxy is not a valid proxy object created with #createContextualProxy of this ContextService 42 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ContextService Example 1 @Resource ContextService ctxSvc; MyAppIntf proxy = ctxSvc.createContextualProxy (myAppImpl, MyAppIntf.class); // invoke at a later time, possibly in a different app // component proxy.doSomething(); 43 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ContextService Example 2 // In application public interface MessageProcessor { public void processMessage(Message msg) … } // Within servlet or EJB method… @Resource ContextService ctxSvc; void businessMethod() { MessageProcessor msgProcessor = … // Wrap with the current context MessageProcessor proxy = ctxSvc.createContextualProxy (msgProcessor, MessageProcessor.class); // Store the contextual proxy object somewhere for running later. store.putIt(proxy); … 44 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ContextService Example 2 (cont’d) // Elsewhere, in a different thread, retrieve the MessageProcessor contextual proxy // object from the store MessageProcessor proxy = store.getIt(); // The proxy method processMessage() is invoked on // this thread, but with the context of the servlet or // EJB that created it. proxy.processMessage(msg); 45 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. ContextService Example 3 (Serialization in a web application) public class MyWork implements Callable<Void>, Serializable { … } // in Servlet A Callable mywork = contextService.createContextualProxy(new MyWork(), Callable.class); try (ObjectOutputStream oos = …) { oos.writeObject(mywork); } // in Servlet B try (ObjectInputStream ois = …) { myWork = (Callable)ois.readObject(); managedExecutorService.submit(myWork); … 46 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Program Agenda Overview Managed Objects Context & Transaction Summary Resources 47 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Context & Transaction Context Propagation Types of container context: – Class loading, JNDI namespace, security identity – Configurable, extensible Container context captured to be applied on execution thread, and to be applied on proxy invocation time. Supported in all 4 types of managed objects 48 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Context & Transaction Transaction Management Transaction are typically not propagated to the execution tasks UserTransaction from JTA is available Contextual proxy objects from ContextService can be run on the same transaction context of the invoking thread 49 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Context & Transaction Example @Resource(lookup=“java:comp/DefaultContextService”) private ContextService cx; @Resource(lookup=“java:comp/UserTransaction”) private UserTransaction ut; … ut.begin(); … MyWork proxy = cx.createContextualProxy(work, map, MyWork.class); … ut.commit(); 50 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Program Agenda Overview Managed Objects Context & Transaction Summary Resources 51 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Summary Provides asynchronous capabilities to Java EE application components Allows Java SE developers simple migration path to Java EE Provides managed objects to applications for submitting tasks and obtaining managed threads Features such as propagation of container context Java EE application developers now have tools to have more advanced control of asynchronous processing. 52 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Program Agenda Overview Managed Objects Context & Transaction Summary Resources 53 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Resources Spec and API docs – http://jcp.org/en/jsr/detail?id=236 – http://concurrency-ee-spec.java.net/javadoc Java EE 7 SDK – http://www.oracle.com/javaee GlassFish 4.0 – http://glassfish.java.net/ Reference Implementation – http://java.net/projects/cu-javaee 54 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. Graphic Section Divider 55 Copyright © 2013 Oracle and/or its affiliates. All rights reserved. 56 Copyright © 2013 Oracle and/or its affiliates. All rights reserved.