java.util.concurrent
package from JavaSE. For the JavaEE stack, the classes of managed resources are located in the javax.enterprise.concurrent
package, while access to the objects of these classes is through resource embedding using the @Resource
annotation, or through the JNDI context (in particular, InitialContext). At the same time, the possibility of using the Future / ScheduledFuture / CompletableFuture objects, which are usual for a multithreaded environment, inside JavaEE applications was added. <domain application-root="${com.sun.aas.instanceRoot}/applications" version="25" log-root="${com.sun.aas.instanceRoot}/logs"> <resources> <context-service object-type="system-all" jndi-name="concurrent/__defaultContextService" /> <managed-executor-service object-type="system-all" jndi-name="concurrent/__defaultManagedExecutorService" /> <managed-scheduled-executor-service object-type="system-all" jndi-name="concurrent/__defaultManagedScheduledExecutorService" /> <managed-thread-factory object-type="system-all" jndi-name="concurrent/__defaultManagedThreadFactory" /> </resources> <servers> <server config-ref="server-config" name="server"> <resource-ref ref="concurrent/__defaultContextService" /> <resource-ref ref="concurrent/__defaultManagedExecutorService" /> <resource-ref ref="concurrent/__defaultManagedScheduledExecutorService" /> <resource-ref ref="concurrent/__defaultManagedThreadFactory" /> </server> </servers> </domain>
create-managed-executor-service
command allows you to create new ManagedExecutorService resources: @Resource(lookup = "concurrent/OtusExecutorService") ManagedExecutorService executor; InitialContext context = new InitialContext(); ManagedExecutorService managedExecutorServiceWithContext = (ManagedExecutorService) context.lookup( "concurrent/OtusExecutorService");
@Resource
annotation @Resource
the lookup parameter is optional and if it is not defined by the developer in the application code, then the container injects default resources with the prefix __default
in the name. In this case, for the developer, the code becomes even more concise: @Resource ManagedExecutorService executor;
execute()
and submit()
methods, you can run tasks inside the container that implement the Runnable or Callable interface.begin()
method and completing with the commit()
methods, committing changes, or rollback()
, rolling back the actions taken. public class TransactionSupportCallableTask implements Callable<String> { private int messageIndex; public TransactionSupportCallableTask(int messageId) { this. messageIndex = messageId; } public String call() { UserTransaction tx = lookupUserTransaction(); String message = null; try { tx.begin(); message = getMessage(messageIndex); tx.commit(); } catch (Exception e) { e.printStackTrace(); try { tx.rollback(); } catch (Exception e1) { e1.printStackTrace(); } } return message; } private void getMessage(int index) { … } private UserTransaction lookupUserTransaction () { … } }
@WebServlet("/task") public class ManagedExecutorServiceServlet extends HttpServlet { @Resource(lookup = "concurrent/OtusExecutorService") ManagedExecutorService executor; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Future<String> futureResult = executor.submit(new TransactionSupportCallableTask(Random.nextInt(100))); while (!futureResult.isDone()) { try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } try { response.getWriter().write("Callable task has received message with following content '" + futureResult.get() + "'"); } catch(Exception e) { e.printStackTrace(); } } }
asadmin
utility has the create-managed-scheduled-executor-service
command @Resource(lookup = "concurrent/OtusScheduledExecutorService") ManagedScheduledExecutorService scheduledExecutor;
schedule()
, which accepts tasks like Runnable or Callable as input, and scheduleAtFixedRate()
, which additionally determines the initial delay in task execution and specifies the interval of repetitions in TimeUnit (seconds, minutes, etc. .). @WebServlet("/scheduledTask") public class ManagedScheduledExecutorServiceServlet extends HttpServlet { @Resource(lookup = "concurrent/OtusScheduledExecutorService") ManagedScheduledExecutorService scheduledExecutor; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ScheduledFuture<String> futureResult = scheduledExecutor.schedule( new TransactionSupportCallableTask(Random.nextInt(100)), 5, TimeUnit.SECONDS); while (!futureResult.isDone()) { try { Thread.sleep(50); // Wait } catch (InterruptedException e) { e.printStackTrace(); } } try { response.getWriter().write("Callable task received message with following content '" + futureResult.get() + "'"); } catch ( Exception e) { e.printStackTrace(); } } }
@Resource ManagedThreadFactory factory;
public class SimpleThreadTask implements Runnable { private String friend; public SimpleThreadTask(String friend){ this.friend = friend; } @Override public void run() { System.out.println("Hello, " + friend); } }
@WebServlet("/thread") public class ManagedThreadFactoryServlet extends HttpServlet { @Resource ManagedThreadFactory factory; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Thread thread = factory.newThread(new SimpleThreadTask("Otus")); thread.setName("ManagedThreadFromPool"); thread.setPriority(7); thread.start(); response.getWriter().write("Custom thread has been running."); } }
java.lang.reflect.Proxy
), which allow generating dynamic implementations of the required interfaces, whose capabilities are actively used for the tasks of creating database connections and transaction management, are used for various AOP interceptors and so on. Moreover, for proxies created via JavaEE contextual services, it is supposed to work within the framework of a common JNDI context, a security context and a container class wizard. @Resource ContextService service;
public class SampleProxyTask implements Runnable { @Override public void run() { // Subject subject = Subject.getSubject(AccessController.getContext()); logInfo(subject.getPrincipals()); // calculateSmth(); } private void calculateSmth() { … } private void logInfo(Set<Principal> subject) { … } }
@Stateless public class ContextServiceBean { @Resource ContextService service; @Resource ManagedExecutorService executor; public void perform(Runnable task) { Runnable proxy = service.createContextualProxy(task, Runnable.class); executor.submit(proxy); } }
@WebServlet("/context") public class ContextServiceServlet extends HttpServlet { @Inject ContextServiceBean contextServiceBean; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { contextServiceBean.perform(new SampleProxyTask()); } }
Source: https://habr.com/ru/post/421809/
All Articles