blob: 1f1b8917269e892b2b1b0ac2dc5623e42b162081 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Apache TomEE</title>
<meta name="description"
content="Apache TomEE is a lightweight, yet powerful, JavaEE Application server with feature rich tooling." />
<meta name="keywords" content="tomee,asf,apache,javaee,jee,shade,embedded,test,junit,applicationcomposer,maven,arquillian" />
<meta name="author" content="Luka Cvetinovic for Codrops" />
<link rel="icon" href="../../favicon.ico">
<link rel="icon" type="image/png" href="../../favicon.png">
<meta name="msapplication-TileColor" content="#80287a">
<meta name="theme-color" content="#80287a">
<link rel="stylesheet" type="text/css" href="../../css/normalize.css">
<link rel="stylesheet" type="text/css" href="../../css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="../../css/owl.css">
<link rel="stylesheet" type="text/css" href="../../css/animate.css">
<link rel="stylesheet" type="text/css" href="../../fonts/font-awesome-4.1.0/css/font-awesome.min.css">
<link rel="stylesheet" type="text/css" href="../../fonts/eleganticons/et-icons.css">
<link rel="stylesheet" type="text/css" href="../../css/jqtree.css">
<link rel="stylesheet" type="text/css" href="../../css/idea.css">
<link rel="stylesheet" type="text/css" href="../../css/cardio.css">
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-2717626-1']);
_gaq.push(['_setDomainName', 'apache.org']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body>
<div class="preloader">
<img src="../../img/loader.gif" alt="Preloader image">
</div>
<nav class="navbar">
<div class="container">
<div class="row"> <div class="col-md-12">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">
<span>
<img src="../../img/logo-active.png">
</span>
Apache TomEE
</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right main-nav">
<li><a href="../../docs.html">Documentation</a></li>
<li><a href="../../community/index.html">Community</a></li>
<li><a href="../../security/security.html">Security</a></li>
<li><a href="../../download-ng.html">Downloads</a></li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div></div>
</div>
<!-- /.container-fluid -->
</nav>
<div id="main-block" class="container main-block">
<div class="row title">
<div class="col-md-12">
<div class='page-header'>
<h1>Concurrency Utilities for Java EE</h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>In this example will be used <a href="https://docs.oracle.com/javaee/7/tutorial/concurrency-utilities.htm">Concurrency Utilities for Java EE</a>, or JSR 236.</p>
</div>
<div class="paragraph">
<p>This standard allows application developers to use concurrency utilities managed by the application server.
In this way, the developer no longer has the responsibility to manually manage thread polls or threads.
Also, in a non-managed Thread object, the container cannot guarantee that other Java EE platform services work correctly. For these reasons, it is recommended the usage of managed threads whenever the need arise.
More information can be found <a href="https://docs.oracle.com/javaee/7/tutorial/concurrency-utilities001.htm">here</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_main_components_of_the_concurrency_utilities">Main Components of the Concurrency Utilities</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The standard specifies main components of the concurrency utilities. In short, these components are managed objects that offer concurrency facilities. These objects, since are managed by the application, can be injected either using CDI, either JNDI. More information can be found <a href="https://docs.oracle.com/javaee/7/tutorial/concurrency-utilities002.htm">here</a>.</p>
</div>
<div class="sect2">
<h3 id="_managedexecutorservice">ManagedExecutorService</h3>
<div class="paragraph">
<p>A <code>ManagedExecutorService</code> is an object that allows application developers to submit tasks asynchronously. Tasks are executed on threads that are managed by the container.</p>
</div>
<div class="sect3">
<h4 id="_example">Example</h4>
<div class="paragraph">
<p>Here is a class that uses a <code>ManagedExecutorService</code> (full code can be found <a href="https://github.com/apache/tomee/blob/master/examples/concurrency-utils/src/main/java/org/superbiz/executor/ManagedService.java">here</a>):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">@RequestScoped
public class ManagedService {
@Resource
private ManagedExecutorService executor;
public CompletableFuture&lt;Integer&gt; asyncTask(final int value) {
return CompletableFuture
.supplyAsync(longTask(value, 100, null), executor)
.thenApply(i -&gt; i + 1);
}
public CompletableFuture&lt;Integer&gt; asyncTaskWithException(final int value) {
return CompletableFuture
.supplyAsync(longTask(value, 100, "Planned exception"), executor)
.thenApply(i -&gt; i + 1);
}
private Supplier&lt;Integer&gt; longTask(final int value,
final int taskDurationMs,
final String errorMessage) {
return () -&gt; {
if (nonNull(errorMessage)) {
throw new RuntimeException(errorMessage);
}
try {
TimeUnit.MILLISECONDS.sleep(taskDurationMs);
} catch (InterruptedException e) {
throw new RuntimeException("Problem while waiting");
}
return value + 1;
};
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>ManagedExecutorService</code> object, being an managed object, is injected using the <code>@Resource</code> annotation.</p>
</div>
<div class="paragraph">
<p>This example simulates a long running computation, defined in the <code>longTask</code> method.</p>
</div>
<div class="paragraph">
<p>The capabilities of <code>ManagedExecutorService</code> are exemplified in the <code>asyncTask</code> and <code>asyncTaskWithException</code> methods.
Both methods invoke the <code>longTask</code> method defined above; each execution of <code>longTask</code> is performed in a thread managed by the application.
The method <code>asyncTask</code> simulates a successful execution, while the <code>asyncTaskWithException</code> simulates a execution that will throw an exception.</p>
</div>
<div class="paragraph">
<p>The methods are used in the following test class (full example can be found <a href="https://github.com/apache/tomee/blob/master/examples/concurrency-utils/src/test/java/org/superbiz/executor/ManagedServiceTest.java">here</a>):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">@RunWith(Arquillian.class)
public class ManagedServiceTest {
@Inject
private ManagedService managedService;
@Deployment()
public static final WebArchive app() {
return ShrinkWrap.create(WebArchive.class, "example.war")
.addClasses(ManagedService.class)
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
}
@Test
public void managedInvocationTest() {
final CompletableFuture&lt;Integer&gt; future = managedService.asyncTask(1);
try {
assertEquals(3, future.get(200, TimeUnit.MILLISECONDS).intValue());
} catch (Exception e) {
fail("Unexpected exception" + e);
}
}
@Test(expected = TimeoutException.class)
public void managedInvocationTestWithTimeout() throws InterruptedException, ExecutionException, TimeoutException {
final CompletableFuture&lt;Integer&gt; future = managedService.asyncTask(1);
future.get(10, TimeUnit.MILLISECONDS);
}
@Test
public void managedInvocationTestWithException() {
final CompletableFuture&lt;Integer&gt; future = managedService.asyncTaskWithException(1);
try {
future.get(200, TimeUnit.MILLISECONDS);
} catch (ExecutionException e) {
assertEquals("Planned exception", e.getCause().getMessage());
} catch (Exception e) {
fail("Unexpected exception" + e);
}
}
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_managedscheduledexecutorservice">ManagedScheduledExecutorService</h3>
<div class="paragraph">
<p>A <code>ManagedScheduledExecutorService</code> is an object that allows developers to execute tasks asynchronously at specific times. The tasks are executed on threads started by the container.</p>
</div>
<div class="sect3">
<h4 id="_example_2">Example</h4>
<div class="paragraph">
<p>Full example can be found <a href="https://github.com/apache/tomee/blob/master/examples/concurrency-utils/src/main/java/org/superbiz/executor/ManagedScheduledService.java">here</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">@RequestScoped
public class ManagedScheduledService {
@Resource
private ManagedScheduledExecutorService executor;
public Future&lt;Integer&gt; singleFixedDelayTask(final int value,
final String errorMessage) {
return executor.schedule(
longCallableTask(value, 10, errorMessage), 100, TimeUnit.MILLISECONDS);
}
public ScheduledFuture&lt;?&gt; periodicFixedDelayTask(final int value,
final String errorMessage,
final CountDownLatch countDownLatch) {
return executor.scheduleAtFixedRate(
longRunnableTask(value, 10, errorMessage, countDownLatch), 0, 100, TimeUnit.MILLISECONDS);
}
private Runnable longRunnableTask(final int value,
final int taskDurationMs,
final String errorMessage,
final CountDownLatch countDownLatch) {
return () -&gt; {
failOrWait(taskDurationMs, errorMessage);
Integer result = value + 1;
countDownLatch.countDown();
};
}
private Callable&lt;Integer&gt; longCallableTask(final int value,
final int taskDurationMs,
final String errorMessage) {
return () -&gt; {
failOrWait(taskDurationMs, errorMessage);
return value + 1;
};
}
private void failOrWait(final int taskDurationMs,
final String errorMessage) {
if (nonNull(errorMessage)) {
throw new RuntimeException(errorMessage);
}
try {
TimeUnit.MILLISECONDS.sleep(taskDurationMs);
} catch (InterruptedException e) {
throw new RuntimeException("Problem while waiting");
}
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This example also defines a method, <code>longCallableTask</code>, simulating the execution of a long running computation.</p>
</div>
<div class="paragraph">
<p>The method <code>singleFixedDelayTask</code> schedules a long running task (by calling <code>longCallableTask</code>), but the execution will start after 100 ms.
The method <code>periodicFixedDelayTask</code> schedules tasks to be run periodically, after each 100 ms, with an initial delay of 0.</p>
</div>
<div class="paragraph">
<p>The methods are used in the following test class (full code can be found <a href="https://github.com/apache/tomee/blob/master/examples/concurrency-utils/src/test/java/org/superbiz/executor/ManagedScheduledServiceTest.java">here</a>):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">@RunWith(Arquillian.class)
public class ManagedScheduledServiceTest {
@Inject
private ManagedScheduledService scheduledService;
@Deployment()
public static final WebArchive app() {
return ShrinkWrap.create(WebArchive.class, "example.war")
.addClasses(ManagedScheduledService.class)
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
}
@Test
public void singleFixedDelayTask() throws InterruptedException, ExecutionException, TimeoutException {
final Future&lt;Integer&gt; futureA = scheduledService.singleFixedDelayTask(1, null);
final Future&lt;Integer&gt; futureB = scheduledService.singleFixedDelayTask(50, null);
assertEquals(2, futureA.get(200, TimeUnit.MILLISECONDS).intValue());
assertEquals(51, futureB.get(200, TimeUnit.MILLISECONDS).intValue());
}
@Test
public void periodicFixedDelayTask() throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(4); // execute 4 times
final ScheduledFuture&lt;?&gt; scheduledFuture = scheduledService.periodicFixedDelayTask(1, null, countDownLatch);
countDownLatch.await(500, TimeUnit.MILLISECONDS);
if (!scheduledFuture.isCancelled()) {
scheduledFuture.cancel(true);
}
}
@Test
public void singleFixedDelayTaskWithException() {
final Future&lt;Integer&gt; future = scheduledService.singleFixedDelayTask(1, "Planned exception");
try {
future.get(200, TimeUnit.MILLISECONDS);
} catch (ExecutionException e) {
assertEquals("Planned exception", e.getCause().getMessage());
} catch (Exception e) {
fail("Unexpected exception" + e);
}
}
@Test
public void periodicFixedDelayTaskWithException() {
final CountDownLatch countDownLatch = new CountDownLatch(1);
final ScheduledFuture&lt;?&gt; scheduledFuture = scheduledService.periodicFixedDelayTask(1, "Planned exception", countDownLatch);
try {
countDownLatch.await(200, TimeUnit.MILLISECONDS);
scheduledFuture.get(200, TimeUnit.MILLISECONDS);
} catch (ExecutionException e) {
assertEquals("Planned exception", e.getCause().getMessage());
} catch (Exception e) {
fail("Unexpected exception" + e);
}
if (!scheduledFuture.isCancelled()) {
scheduledFuture.cancel(true);
}
}
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_managedthreadfactory">ManagedThreadFactory</h3>
<div class="paragraph">
<p>A <code>ManagedThreadFactory</code> is an object that allows developers to create container managed threads.</p>
</div>
<div class="sect3">
<h4 id="_example_3">Example</h4>
<div class="paragraph">
<p>Full example can be found <a href="https://github.com/apache/tomee/blob/master/examples/concurrency-utils/src/main/java/org/superbiz/executor/ThreadFactoryService.java">here</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">@RequestScoped
public class ThreadFactoryService {
@Resource
private ManagedThreadFactory factory;
public void asyncTask(final LongTask longTask) throws InterruptedException {
final Thread thread = factory.newThread(longTask);
thread.setName("pretty asyncTask");
thread.start();
}
public void asyncHangingTask(final Runnable longTask) {
final Thread thread = factory.newThread(longTask);
thread.setName("pretty asyncHangingTask");
thread.start();
if (thread.isAlive()) {
thread.interrupt();
}
}
public static class LongTask implements Runnable {
private final int value;
private final long taskDurationMs;
private final CountDownLatch countDownLatch;
private int result;
private AtomicBoolean isTerminated = new AtomicBoolean(false);
public LongTask(final int value,
final long taskDurationMs,
final CountDownLatch countDownLatch) {
this.value = value;
this.taskDurationMs = taskDurationMs;
this.countDownLatch = countDownLatch;
}
public int getResult() {
return result;
}
public boolean getIsTerminated() {
return isTerminated.get();
}
@Override
public void run() {
try {
TimeUnit.MILLISECONDS.sleep(taskDurationMs);
} catch (InterruptedException e) {
isTerminated.set(true);
countDownLatch.countDown();
throw new RuntimeException("Problem while waiting");
}
result = value + 1;
countDownLatch.countDown();
}
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This example defines a class implementing <code>Runnable</code>, executing a long running task in the <code>run</code> method.</p>
</div>
<div class="paragraph">
<p>The method <code>asyncTask</code> just creates a managed thread (using the injected <code>ManagedThreadFactory</code>) then starts it.
The method <code>asyncHangingTask</code> also creates a managed thread, starts it, but then stops it.</p>
</div>
<div class="paragraph">
<p>The following class tests these methods (full code can be found <a href="https://github.com/apache/tomee/blob/master/examples/concurrency-utils/src/test/java/org/superbiz/executor/ThreadFactoryServiceTest.java">here</a>):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">@RunWith(Arquillian.class)
public class ThreadFactoryServiceTest {
@Inject
private ThreadFactoryService factoryService;
@Deployment()
public static final WebArchive app() {
return ShrinkWrap.create(WebArchive.class, "example.war")
.addClasses(ThreadFactoryService.class)
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
}
@Test
public void asyncTask() throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1);
final LongTask longTask = new LongTask(1, 50, countDownLatch);
factoryService.asyncTask(longTask);
countDownLatch.await(200, TimeUnit.MILLISECONDS);
assertEquals(2, longTask.getResult());
}
@Test
public void asyncHangingTask() throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1);
final LongTask longTask = new LongTask(1, 1000000, countDownLatch);
factoryService.asyncHangingTask(longTask);
countDownLatch.await(200, TimeUnit.MILLISECONDS);
assertTrue(longTask.getIsTerminated());
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Full project example can be found <a href="https://github.com/apache/tomee/tree/master/examples/concurrency-utils">here</a>.
It&#8217;s a Maven project, and all the tests can be executed by running <code>mvn clean install</code> command.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-sm-6 text-center-mobile">
<h3 class="white">Be simple. Be certified. Be Tomcat.</h3>
<h5 class="light regular light-white">"A good application in a good server"</h5>
<ul class="social-footer">
<li><a href="https://www.facebook.com/ApacheTomEE/"><i class="fa fa-facebook"></i></a></li>
<li><a href="https://twitter.com/apachetomee"><i class="fa fa-twitter"></i></a></li>
<li><a href="https://plus.google.com/communities/105208241852045684449"><i class="fa fa-google-plus"></i></a></li>
</ul>
</div>
<div class="col-sm-6 text-center-mobile">
<div class="row opening-hours">
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../latest/docs/" class="white">Documentation</a></h5>
<ul class="list-unstyled">
<li><a href="../../latest/docs/admin/configuration/index.html" class="regular light-white">How to configure</a></li>
<li><a href="../../latest/docs/admin/file-layout.html" class="regular light-white">Dir. Structure</a></li>
<li><a href="../../latest/docs/developer/testing/index.html" class="regular light-white">Testing</a></li>
<li><a href="../../latest/docs/admin/cluster/index.html" class="regular light-white">Clustering</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../latest/examples/" class="white">Examples</a></h5>
<ul class="list-unstyled">
<li><a href="../../latest/examples/simple-cdi-interceptor.html" class="regular light-white">CDI Interceptor</a></li>
<li><a href="../../latest/examples/rest-cdi.html" class="regular light-white">REST with CDI</a></li>
<li><a href="../../latest/examples/ejb-examples.html" class="regular light-white">EJB</a></li>
<li><a href="../../latest/examples/jsf-managedBean-and-ejb.html" class="regular light-white">JSF</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../community/index.html" class="white">Community</a></h5>
<ul class="list-unstyled">
<li><a href="../../community/contributors.html" class="regular light-white">Contributors</a></li>
<li><a href="../../community/social.html" class="regular light-white">Social</a></li>
<li><a href="../../community/sources.html" class="regular light-white">Sources</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../security/index.html" class="white">Security</a></h5>
<ul class="list-unstyled">
<li><a href="http://apache.org/security" target="_blank" class="regular light-white">Apache Security</a></li>
<li><a href="http://apache.org/security/projects.html" target="_blank" class="regular light-white">Security Projects</a></li>
<li><a href="http://cve.mitre.org" target="_blank" class="regular light-white">CVE</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="row bottom-footer text-center-mobile">
<div class="col-sm-12 light-white">
<p>Copyright &copy; 1999-2016 The Apache Software Foundation, Licensed under the Apache License, Version 2.0. Apache TomEE, TomEE, Apache, the Apache feather logo, and the Apache TomEE project logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.</p>
</div>
</div>
</div>
</footer>
<!-- Holder for mobile navigation -->
<div class="mobile-nav">
<ul>
<li><a hef="../../latest/docs/admin/index.html">Administrators</a>
<li><a hef="../../latest/docs/developer/index.html">Developers</a>
<li><a hef="../../latest/docs/advanced/index.html">Advanced</a>
<li><a hef="../../community/index.html">Community</a>
</ul>
<a href="#" class="close-link"><i class="arrow_up"></i></a>
</div>
<!-- Scripts -->
<script src="../../js/jquery-1.11.1.min.js"></script>
<script src="../../js/owl.carousel.min.js"></script>
<script src="../../js/bootstrap.min.js"></script>
<script src="../../js/wow.min.js"></script>
<script src="../../js/typewriter.js"></script>
<script src="../../js/jquery.onepagenav.js"></script>
<script src="../../js/tree.jquery.js"></script>
<script src="../../js/highlight.pack.js"></script>
<script src="../../js/main.js"></script>
</body>
</html>