You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by da...@apache.org on 2012/09/06 13:08:12 UTC
svn commit: r1381557 - in /activemq/trunk/activemq-core/src:
main/java/org/apache/activemq/thread/ main/java/org/apache/activemq/util/
test/java/org/apache/activemq/util/
Author: davsclaus
Date: Thu Sep 6 11:08:11 2012
New Revision: 1381557
URL: http://svn.apache.org/viewvc?rev=1381557&view=rev
Log:
AMQ-4026: Introduced ThreadPoolUtils to shutdown thread pools in a more graceful manner. Improved logging for lifecycle of thread pools and tasks being executed.
Added:
activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/StopWatch.java (with props)
activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/ThreadPoolUtils.java (with props)
activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/TimeUtils.java (with props)
activemq/trunk/activemq-core/src/test/java/org/apache/activemq/util/StopWatchTest.java (with props)
Modified:
activemq/trunk/activemq-core/src/main/java/org/apache/activemq/thread/DedicatedTaskRunner.java
activemq/trunk/activemq-core/src/main/java/org/apache/activemq/thread/PooledTaskRunner.java
activemq/trunk/activemq-core/src/main/java/org/apache/activemq/thread/TaskRunnerFactory.java
Modified: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/thread/DedicatedTaskRunner.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/thread/DedicatedTaskRunner.java?rev=1381557&r1=1381556&r2=1381557&view=diff
==============================================================================
--- activemq/trunk/activemq-core/src/main/java/org/apache/activemq/thread/DedicatedTaskRunner.java (original)
+++ activemq/trunk/activemq-core/src/main/java/org/apache/activemq/thread/DedicatedTaskRunner.java Thu Sep 6 11:08:11 2012
@@ -16,11 +16,15 @@
*/
package org.apache.activemq.thread;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
*
*/
class DedicatedTaskRunner implements TaskRunner {
+ private static final Logger LOG = LoggerFactory.getLogger(DedicatedTaskRunner.class);
private final Task task;
private final Thread thread;
@@ -29,11 +33,15 @@ class DedicatedTaskRunner implements Tas
private boolean pending;
private boolean shutdown;
- public DedicatedTaskRunner(Task task, String name, int priority, boolean daemon) {
+ public DedicatedTaskRunner(final Task task, String name, int priority, boolean daemon) {
this.task = task;
thread = new Thread(name) {
public void run() {
- runTask();
+ try {
+ runTask();
+ } finally {
+ LOG.trace("Run task done: {}", task);
+ }
}
};
thread.setDaemon(daemon);
@@ -61,6 +69,7 @@ class DedicatedTaskRunner implements Tas
* @throws InterruptedException
*/
public void shutdown(long timeout) throws InterruptedException {
+ LOG.trace("Shutdown timeout: {} task: {}", task);
synchronized (mutex) {
shutdown = true;
pending = true;
@@ -95,6 +104,7 @@ class DedicatedTaskRunner implements Tas
}
}
+ LOG.trace("Running task {}", task);
if (!task.iterate()) {
// wait to be notified.
synchronized (mutex) {
Modified: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/thread/PooledTaskRunner.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/thread/PooledTaskRunner.java?rev=1381557&r1=1381556&r2=1381557&view=diff
==============================================================================
--- activemq/trunk/activemq-core/src/main/java/org/apache/activemq/thread/PooledTaskRunner.java (original)
+++ activemq/trunk/activemq-core/src/main/java/org/apache/activemq/thread/PooledTaskRunner.java Thu Sep 6 11:08:11 2012
@@ -18,11 +18,15 @@ package org.apache.activemq.thread;
import java.util.concurrent.Executor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
*
*/
class PooledTaskRunner implements TaskRunner {
+ private static final Logger LOG = LoggerFactory.getLogger(PooledTaskRunner.class);
private final int maxIterationsPerRun;
private final Executor executor;
private final Task task;
@@ -32,7 +36,7 @@ class PooledTaskRunner implements TaskRu
private boolean iterating;
private volatile Thread runningThread;
- public PooledTaskRunner(Executor executor, Task task, int maxIterationsPerRun) {
+ public PooledTaskRunner(Executor executor, final Task task, int maxIterationsPerRun) {
this.executor = executor;
this.maxIterationsPerRun = maxIterationsPerRun;
this.task = task;
@@ -42,6 +46,7 @@ class PooledTaskRunner implements TaskRu
try {
runTask();
} finally {
+ LOG.trace("Run task done: {}", task);
runningThread = null;
}
}
@@ -84,6 +89,7 @@ class PooledTaskRunner implements TaskRu
* @throws InterruptedException
*/
public void shutdown(long timeout) throws InterruptedException {
+ LOG.trace("Shutdown timeout: {} task: {}", task);
synchronized (runable) {
shutdown = true;
// the check on the thread is done
@@ -119,6 +125,7 @@ class PooledTaskRunner implements TaskRu
boolean done = false;
try {
for (int i = 0; i < maxIterationsPerRun; i++) {
+ LOG.trace("Running task iteration {} - {}", i, task);
if (!task.iterate()) {
done = true;
break;
Modified: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/thread/TaskRunnerFactory.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/thread/TaskRunnerFactory.java?rev=1381557&r1=1381556&r2=1381557&view=diff
==============================================================================
--- activemq/trunk/activemq-core/src/main/java/org/apache/activemq/thread/TaskRunnerFactory.java (original)
+++ activemq/trunk/activemq-core/src/main/java/org/apache/activemq/thread/TaskRunnerFactory.java Thu Sep 6 11:08:11 2012
@@ -26,6 +26,10 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
+import org.apache.activemq.util.ThreadPoolUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* Manages the thread pool for long running tasks. Long running tasks are not
* always active but when they are active, they may need a few iterations of
@@ -37,6 +41,7 @@ import java.util.concurrent.atomic.Atomi
*/
public class TaskRunnerFactory implements Executor {
+ private static final Logger LOG = LoggerFactory.getLogger(TaskRunnerFactory.class);
private ExecutorService executor;
private int maxIterationsPerRun;
private String name;
@@ -44,6 +49,7 @@ public class TaskRunnerFactory implement
private boolean daemon;
private AtomicLong id = new AtomicLong(0);
private boolean dedicatedTaskRunner;
+ private long shutdownAwaitTermination = 30000;
private AtomicBoolean initDone = new AtomicBoolean(false);
private int maxThreadPoolSize = Integer.MAX_VALUE;
private RejectedExecutionHandler rejectedTaskHandler = null;
@@ -82,12 +88,14 @@ public class TaskRunnerFactory implement
} else if (executor == null) {
executor = createDefaultExecutor();
}
+ LOG.debug("Initialized TaskRunnerFactory[{}] using ExecutorService: {}", name, executor);
}
}
public void shutdown() {
if (executor != null) {
- executor.shutdownNow();
+ ThreadPoolUtils.shutdown(executor, shutdownAwaitTermination);
+ executor = null;
}
initDone.set(false);
}
@@ -107,6 +115,7 @@ public class TaskRunnerFactory implement
public void execute(Runnable runnable, String name) {
init();
+ LOG.trace("Execute[{}] runnable: {}", name, runnable);
if (executor != null) {
executor.execute(runnable);
} else {
@@ -117,9 +126,12 @@ public class TaskRunnerFactory implement
protected ExecutorService createDefaultExecutor() {
ThreadPoolExecutor rc = new ThreadPoolExecutor(0, getMaxThreadPoolSize(), 30, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), new ThreadFactory() {
public Thread newThread(Runnable runnable) {
- Thread thread = new Thread(runnable, name + "-" + id.incrementAndGet());
+ String threadName = name + "-" + id.incrementAndGet();
+ Thread thread = new Thread(runnable, threadName);
thread.setDaemon(daemon);
thread.setPriority(priority);
+
+ LOG.trace("Created thread[{}]: {}", threadName, thread);
return thread;
}
});
@@ -192,4 +204,13 @@ public class TaskRunnerFactory implement
public void setRejectedTaskHandler(RejectedExecutionHandler rejectedTaskHandler) {
this.rejectedTaskHandler = rejectedTaskHandler;
}
+
+ public long getShutdownAwaitTermination() {
+ return shutdownAwaitTermination;
+ }
+
+ public void setShutdownAwaitTermination(long shutdownAwaitTermination) {
+ this.shutdownAwaitTermination = shutdownAwaitTermination;
+ }
+
}
Added: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/StopWatch.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/StopWatch.java?rev=1381557&view=auto
==============================================================================
--- activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/StopWatch.java (added)
+++ activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/StopWatch.java Thu Sep 6 11:08:11 2012
@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.util;
+
+/**
+ * A very simple stop watch.
+ * <p/>
+ * This implementation is not thread safe and can only time one task at any given time.
+ *
+ * @version
+ */
+public final class StopWatch {
+
+ private long start;
+ private long stop;
+
+ /**
+ * Starts the stop watch
+ */
+ public StopWatch() {
+ this(true);
+ }
+
+ /**
+ * Creates the stop watch
+ *
+ * @param started whether it should start immediately
+ */
+ public StopWatch(boolean started) {
+ if (started) {
+ restart();
+ }
+ }
+
+ /**
+ * Starts or restarts the stop watch
+ */
+ public void restart() {
+ start = System.currentTimeMillis();
+ stop = 0;
+ }
+
+ /**
+ * Stops the stop watch
+ *
+ * @return the time taken in millis.
+ */
+ public long stop() {
+ stop = System.currentTimeMillis();
+ return taken();
+ }
+
+ /**
+ * Returns the time taken in millis.
+ *
+ * @return time in millis
+ */
+ public long taken() {
+ if (start > 0 && stop > 0) {
+ return stop - start;
+ } else if (start > 0) {
+ return System.currentTimeMillis() - start;
+ } else {
+ return 0;
+ }
+ }
+}
Propchange: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/StopWatch.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/StopWatch.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/ThreadPoolUtils.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/ThreadPoolUtils.java?rev=1381557&view=auto
==============================================================================
--- activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/ThreadPoolUtils.java (added)
+++ activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/ThreadPoolUtils.java Thu Sep 6 11:08:11 2012
@@ -0,0 +1,157 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.util;
+
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ */
+public class ThreadPoolUtils {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ThreadPoolUtils.class);
+
+ // TODO: Should be 30 sec
+ // but lowered due some unit tests dont yet properly shutdown, so want to run these a bit faster
+ public static final long DEFAULT_SHUTDOWN_AWAIT_TERMINATION = 10 * 1000L;
+
+ /**
+ * Shutdown the given executor service graceful at first, and then aggressively
+ * if the await termination timeout was hit.
+ * <p/>
+ * This implementation invokes the {@link #shutdown(java.util.concurrent.ExecutorService, long)}
+ * with a timeout value of {@link #DEFAULT_SHUTDOWN_AWAIT_TERMINATION} millis.
+ *
+ * @see #shutdown(java.util.concurrent.ExecutorService, long)
+ */
+ public void shutdown(ExecutorService executorService) {
+ shutdown(executorService, DEFAULT_SHUTDOWN_AWAIT_TERMINATION);
+ }
+
+ /**
+ * Shutdown the given executor service graceful at first, and then aggressively
+ * if the await termination timeout was hit.
+ * <p/>
+ * Will try to perform an orderly shutdown by giving the running threads
+ * time to complete tasks, before going more aggressively by doing a
+ * {@link #shutdownNow(java.util.concurrent.ExecutorService)} which
+ * forces a shutdown. The parameter <tt>shutdownAwaitTermination</tt>
+ * is used as timeout value waiting for orderly shutdown to
+ * complete normally, before going aggressively.
+ *
+ * @param executorService the executor service to shutdown
+ * @param shutdownAwaitTermination timeout in millis to wait for orderly shutdown
+ * @see java.util.concurrent.ExecutorService#shutdown()
+ */
+ public static void shutdown(ExecutorService executorService, long shutdownAwaitTermination) {
+ // code from Apache Camel - org.apache.camel.impl.DefaultExecutorServiceManager
+
+ if (shutdownAwaitTermination <= 0) {
+ throw new IllegalArgumentException("ShutdownAwaitTermination must be a positive number, was: " + shutdownAwaitTermination);
+ }
+
+ // shutting down a thread pool is a 2 step process. First we try graceful, and if that fails, then we go more aggressively
+ // and try shutting down again. In both cases we wait at most the given shutdown timeout value given
+ // (total wait could then be 2 x shutdownAwaitTermination)
+ boolean warned = false;
+ StopWatch watch = new StopWatch();
+ if (!executorService.isShutdown()) {
+ LOG.trace("Shutdown of ExecutorService: {} with await termination: {} millis", executorService, shutdownAwaitTermination);
+ executorService.shutdown();
+ try {
+ if (!awaitTermination(executorService, shutdownAwaitTermination)) {
+ warned = true;
+ LOG.warn("Forcing shutdown of ExecutorService: {} due first await termination elapsed.", executorService);
+ executorService.shutdownNow();
+ // we are now shutting down aggressively, so wait to see if we can completely shutdown or not
+ if (!awaitTermination(executorService, shutdownAwaitTermination)) {
+ LOG.warn("Cannot completely force shutdown of ExecutorService: {} due second await termination elapsed.", executorService);
+ }
+ }
+ } catch (InterruptedException e) {
+ warned = true;
+ LOG.warn("Forcing shutdown of ExecutorService: {} due interrupted.", executorService);
+ // we were interrupted during shutdown, so force shutdown
+ executorService.shutdownNow();
+ }
+
+ // if we logged at WARN level, then report at INFO level when we are complete so the end user can see this in the log
+ if (warned) {
+ LOG.info("Shutdown of ExecutorService: {} is shutdown: {} and terminated: {} took: {}.",
+ new Object[]{executorService, executorService.isShutdown(), executorService.isTerminated(), TimeUtils.printDuration(watch.taken())});
+ } else if (LOG.isDebugEnabled()) {
+ LOG.debug("Shutdown of ExecutorService: {} is shutdown: {} and terminated: {} took: {}.",
+ new Object[]{executorService, executorService.isShutdown(), executorService.isTerminated(), TimeUtils.printDuration(watch.taken())});
+ }
+ }
+ }
+
+ /**
+ * Shutdown now the given executor service aggressively.
+ *
+ * @param executorService the executor service to shutdown now
+ * @return list of tasks that never commenced execution
+ * @see java.util.concurrent.ExecutorService#shutdownNow()
+ */
+ public static List<Runnable> shutdownNow(ExecutorService executorService) {
+ List<Runnable> answer = null;
+ if (!executorService.isShutdown()) {
+ LOG.debug("Forcing shutdown of ExecutorService: {}", executorService);
+ answer = executorService.shutdownNow();
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Shutdown of ExecutorService: {} is shutdown: {} and terminated: {}.",
+ new Object[]{executorService, executorService.isShutdown(), executorService.isTerminated()});
+ }
+ }
+
+ return answer;
+ }
+
+ /**
+ * Awaits the termination of the thread pool.
+ * <p/>
+ * This implementation will log every 5th second at INFO level that we are waiting, so the end user
+ * can see we are not hanging in case it takes longer time to shutdown the pool.
+ *
+ * @param executorService the thread pool
+ * @param shutdownAwaitTermination time in millis to use as timeout
+ * @return <tt>true</tt> if the pool is terminated, or <tt>false</tt> if we timed out
+ * @throws InterruptedException is thrown if we are interrupted during the waiting
+ */
+ public static boolean awaitTermination(ExecutorService executorService, long shutdownAwaitTermination) throws InterruptedException {
+ // log progress every 5th second so end user is aware of we are shutting down
+ StopWatch watch = new StopWatch();
+ long interval = Math.min(5000, shutdownAwaitTermination);
+ boolean done = false;
+ while (!done && interval > 0) {
+ if (executorService.awaitTermination(interval, TimeUnit.MILLISECONDS)) {
+ done = true;
+ } else {
+ LOG.info("Waited {} for ExecutorService: {} to shutdown...", TimeUtils.printDuration(watch.taken()), executorService);
+ // recalculate interval
+ interval = Math.min(5000, shutdownAwaitTermination - watch.taken());
+ }
+ }
+
+ return done;
+ }
+}
Propchange: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/ThreadPoolUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/ThreadPoolUtils.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/TimeUtils.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/TimeUtils.java?rev=1381557&view=auto
==============================================================================
--- activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/TimeUtils.java (added)
+++ activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/TimeUtils.java Thu Sep 6 11:08:11 2012
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.util;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.util.Locale;
+
+/**
+ * Time utils.
+ *
+ * @version
+ */
+public final class TimeUtils {
+
+ private TimeUtils() {
+ }
+
+ /**
+ * Prints the duration in a human readable format as X days Y hours Z minutes etc.
+ *
+ * @param uptime the uptime in millis
+ * @return the time used for displaying on screen or in logs
+ */
+ public static String printDuration(double uptime) {
+ // Code taken from Karaf
+ // https://svn.apache.org/repos/asf/karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/impl/InfoAction.java
+
+ NumberFormat fmtI = new DecimalFormat("###,###", new DecimalFormatSymbols(Locale.ENGLISH));
+ NumberFormat fmtD = new DecimalFormat("###,##0.000", new DecimalFormatSymbols(Locale.ENGLISH));
+
+ uptime /= 1000;
+ if (uptime < 60) {
+ return fmtD.format(uptime) + " seconds";
+ }
+ uptime /= 60;
+ if (uptime < 60) {
+ long minutes = (long) uptime;
+ String s = fmtI.format(minutes) + (minutes > 1 ? " minutes" : " minute");
+ return s;
+ }
+ uptime /= 60;
+ if (uptime < 24) {
+ long hours = (long) uptime;
+ long minutes = (long) ((uptime - hours) * 60);
+ String s = fmtI.format(hours) + (hours > 1 ? " hours" : " hour");
+ if (minutes != 0) {
+ s += " " + fmtI.format(minutes) + (minutes > 1 ? " minutes" : " minute");
+ }
+ return s;
+ }
+ uptime /= 24;
+ long days = (long) uptime;
+ long hours = (long) ((uptime - days) * 24);
+ String s = fmtI.format(days) + (days > 1 ? " days" : " day");
+ if (hours != 0) {
+ s += " " + fmtI.format(hours) + (hours > 1 ? " hours" : " hour");
+ }
+ return s;
+ }
+
+}
Propchange: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/TimeUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/TimeUtils.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: activemq/trunk/activemq-core/src/test/java/org/apache/activemq/util/StopWatchTest.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/util/StopWatchTest.java?rev=1381557&view=auto
==============================================================================
--- activemq/trunk/activemq-core/src/test/java/org/apache/activemq/util/StopWatchTest.java (added)
+++ activemq/trunk/activemq-core/src/test/java/org/apache/activemq/util/StopWatchTest.java Thu Sep 6 11:08:11 2012
@@ -0,0 +1,73 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.util;
+
+import junit.framework.TestCase;
+
+/**
+ *
+ */
+public class StopWatchTest extends TestCase {
+
+ public void testStopWatch() throws Exception {
+ StopWatch watch = new StopWatch();
+ Thread.sleep(200);
+ long taken = watch.stop();
+
+ assertEquals(taken, watch.taken());
+ assertTrue("Should take approx 200 millis, was: " + taken, taken > 150);
+ }
+
+ public void testStopWatchNotStarted() throws Exception {
+ StopWatch watch = new StopWatch(false);
+ long taken = watch.stop();
+ assertEquals(0, taken);
+
+ watch.restart();
+ Thread.sleep(200);
+ taken = watch.stop();
+
+ assertEquals(taken, watch.taken());
+ assertTrue("Should take approx 200 millis, was: " + taken, taken > 150);
+ }
+
+ public void testStopWatchRestart() throws Exception {
+ StopWatch watch = new StopWatch();
+ Thread.sleep(200);
+ long taken = watch.stop();
+
+ assertEquals(taken, watch.taken());
+ assertTrue("Should take approx 200 millis, was: " + taken, taken > 150);
+
+ watch.restart();
+ Thread.sleep(100);
+ taken = watch.stop();
+
+ assertEquals(taken, watch.taken());
+ assertTrue("Should take approx 100 millis, was: " + taken, taken > 50);
+ }
+
+ public void testStopWatchTaken() throws Exception {
+ StopWatch watch = new StopWatch();
+ Thread.sleep(100);
+ long taken = watch.taken();
+ Thread.sleep(100);
+ long taken2 = watch.taken();
+ assertNotSame(taken, taken2);
+ assertTrue(taken2 > taken);
+ }
+}
\ No newline at end of file
Propchange: activemq/trunk/activemq-core/src/test/java/org/apache/activemq/util/StopWatchTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: activemq/trunk/activemq-core/src/test/java/org/apache/activemq/util/StopWatchTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date