Use CountDownLatch instead of sleep while waiting for other threads. Signed-off-by: brunobat <bruno...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/40b41a38 Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/40b41a38 Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/40b41a38 Branch: refs/heads/master Commit: 40b41a38df22fc3f9c531684b8ecbc76edabd5b9 Parents: 2f63669 Author: brunobat <bruno...@gmail.com> Authored: Wed Dec 26 12:30:28 2018 +0000 Committer: brunobat <bruno...@gmail.com> Committed: Wed Dec 26 12:30:28 2018 +0000 ---------------------------------------------------------------------- .../executor/ManagedScheduledService.java | 53 ++++++++++---------- .../superbiz/executor/ThreadFactoryService.java | 4 +- .../executor/ManagedScheduledServiceTest.java | 11 ++-- 3 files changed, 36 insertions(+), 32 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/40b41a38/examples/concurrency-utils/src/main/java/org/superbiz/executor/ManagedScheduledService.java ---------------------------------------------------------------------- diff --git a/examples/concurrency-utils/src/main/java/org/superbiz/executor/ManagedScheduledService.java b/examples/concurrency-utils/src/main/java/org/superbiz/executor/ManagedScheduledService.java index c0f2bdb..e9e2cb5 100644 --- a/examples/concurrency-utils/src/main/java/org/superbiz/executor/ManagedScheduledService.java +++ b/examples/concurrency-utils/src/main/java/org/superbiz/executor/ManagedScheduledService.java @@ -21,6 +21,7 @@ import javax.annotation.Resource; import javax.enterprise.concurrent.ManagedScheduledExecutorService; import javax.enterprise.context.RequestScoped; import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.Future; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -56,15 +57,17 @@ public class ManagedScheduledService { * executor uses a runnable to perform the operations.<br> * If an exception happens, the task will stop and you can catch the exception with the {@link ScheduledFuture}. * - * @param value The value to compute - * @param errorMessage If not null an exception with be thrown with this message + * @param value The value to compute + * @param errorMessage If not null an exception with be thrown with this message + * @param countDownLatch * @return An object where you can cancel the periodic task and check for exceptions. */ public ScheduledFuture<?> periodicFixedDelayTask(final int value, - final String errorMessage) { + final String errorMessage, + final CountDownLatch countDownLatch) { LOGGER.info("longRunnableTask scheduled"); return executor.scheduleAtFixedRate( - longRunnableTask(value, 10, errorMessage), 0, 100, TimeUnit.MILLISECONDS); + longRunnableTask(value, 10, errorMessage, countDownLatch), 0, 100, TimeUnit.MILLISECONDS); } /** @@ -77,22 +80,14 @@ public class ManagedScheduledService { */ private Runnable longRunnableTask(final int value, final int taskDurationMs, - final String errorMessage) { + final String errorMessage, + final CountDownLatch countDownLatch) { return () -> { - if (nonNull(errorMessage)) { - LOGGER.severe("Exception will be thrown"); - throw new RuntimeException(errorMessage); - } - try { - // Simulate a long processing task using TimeUnit to sleep. - TimeUnit.MILLISECONDS.sleep(taskDurationMs); - } catch (InterruptedException e) { - throw new RuntimeException("Problem while waiting"); - } - + failOrWait(taskDurationMs, errorMessage); Integer result = value + 1; LOGGER.info("longRunnableTask complete. Value is " + result); // Cannot return result with a Runnable. + countDownLatch.countDown(); }; } @@ -109,21 +104,25 @@ public class ManagedScheduledService { final String errorMessage) { return () -> { LOGGER.info("longCallableTask start"); - if (nonNull(errorMessage)) { - LOGGER.severe("Exception will be thrown"); - throw new RuntimeException(errorMessage); - } - - try { - // Simulate a long processing task using TimeUnit to sleep. - TimeUnit.MILLISECONDS.sleep(taskDurationMs); - } catch (InterruptedException e) { - throw new RuntimeException("Problem while waiting"); - } + failOrWait(taskDurationMs, errorMessage); LOGGER.info("longCallableTask complete"); // We can return a result with a Callable. return value + 1; }; } + private void failOrWait(final int taskDurationMs, + final String errorMessage) { + if (nonNull(errorMessage)) { + LOGGER.severe("Exception will be thrown"); + throw new RuntimeException(errorMessage); + } + try { + // Simulate a long processing task using TimeUnit to sleep. + TimeUnit.MILLISECONDS.sleep(taskDurationMs); + } catch (InterruptedException e) { + throw new RuntimeException("Problem while waiting"); + } + } + } http://git-wip-us.apache.org/repos/asf/tomee/blob/40b41a38/examples/concurrency-utils/src/main/java/org/superbiz/executor/ThreadFactoryService.java ---------------------------------------------------------------------- diff --git a/examples/concurrency-utils/src/main/java/org/superbiz/executor/ThreadFactoryService.java b/examples/concurrency-utils/src/main/java/org/superbiz/executor/ThreadFactoryService.java index 93df490..a0d0d6c 100644 --- a/examples/concurrency-utils/src/main/java/org/superbiz/executor/ThreadFactoryService.java +++ b/examples/concurrency-utils/src/main/java/org/superbiz/executor/ThreadFactoryService.java @@ -66,7 +66,9 @@ public class ThreadFactoryService { } /** - * Runnable rung task simulating a lengthy operation + * Runnable rung task simulating a lengthy operation. + * In the other test classes we use anonymous classes. + * It's useful to have a "real" class in this case to be able to access the result of the operation. */ public static class LongTask implements Runnable { private final int value; http://git-wip-us.apache.org/repos/asf/tomee/blob/40b41a38/examples/concurrency-utils/src/test/java/org/superbiz/executor/ManagedScheduledServiceTest.java ---------------------------------------------------------------------- diff --git a/examples/concurrency-utils/src/test/java/org/superbiz/executor/ManagedScheduledServiceTest.java b/examples/concurrency-utils/src/test/java/org/superbiz/executor/ManagedScheduledServiceTest.java index 1a859ba..61f9750 100644 --- a/examples/concurrency-utils/src/test/java/org/superbiz/executor/ManagedScheduledServiceTest.java +++ b/examples/concurrency-utils/src/test/java/org/superbiz/executor/ManagedScheduledServiceTest.java @@ -25,6 +25,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import javax.inject.Inject; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.ScheduledFuture; @@ -75,9 +76,10 @@ public class ManagedScheduledServiceTest { */ @Test public void periodicFixedDelayTask() throws InterruptedException { - final ScheduledFuture<?> scheduledFuture = scheduledService.periodicFixedDelayTask(1, null); + final CountDownLatch countDownLatch = new CountDownLatch(4); // execute 4 times + final ScheduledFuture<?> scheduledFuture = scheduledService.periodicFixedDelayTask(1, null, countDownLatch); LOGGER.info("Do some other work while we wait for the tasks"); - TimeUnit.MILLISECONDS.sleep(500); + countDownLatch.await(500, TimeUnit.MILLISECONDS); if (!scheduledFuture.isCancelled()) { scheduledFuture.cancel(true); LOGGER.info("task stopped"); @@ -107,10 +109,11 @@ public class ManagedScheduledServiceTest { */ @Test public void periodicFixedDelayTaskWithException() { - final ScheduledFuture<?> scheduledFuture = scheduledService.periodicFixedDelayTask(1, "Planned exception"); + final CountDownLatch countDownLatch = new CountDownLatch(1); + final ScheduledFuture<?> scheduledFuture = scheduledService.periodicFixedDelayTask(1, "Planned exception", countDownLatch); try { - TimeUnit.MILLISECONDS.sleep(500); + countDownLatch.await(200, TimeUnit.MILLISECONDS); // please note that this thread will pause here until an exception is thrown. // The scheduler uses a Runnable that will never return a result. scheduledFuture.get(200, TimeUnit.MILLISECONDS);