Simulates a stop watch with a lap counter.
/* * JBoss, Home of Professional Open Source * Copyright 2005, JBoss Inc., and individual contributors as indicated * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ import java.io.Serializable; /** * Simulates a stop watch with a <em>lap</em> counter. * * @version <tt>$Revision: 2800 $</tt> * @author <a href="mailto:jason@planet57.com">Jason Dillon</a> */ public class StopWatch implements Serializable, Cloneable { /** The serialVersionUID */ private static final long serialVersionUID = 4628094303187435707L; /** Total time */ protected long total = 0; /** Start time */ protected long start = -1; /** Stop time */ protected long stop = -1; /** The <i>lap</i> count */ protected int count = 0; /** Is the watch started */ protected boolean running = false; /** * Default constructor. */ public StopWatch() { } /** * Construct a StopWatch. * * @param running * Start the watch */ public StopWatch(final boolean running) { if (running) start(); } /** * Start the watch. * * @param reset * True to reset the watch prior to starting. */ public void start(final boolean reset) { if (!running) { if (reset) reset(); start = System.currentTimeMillis(); running = true; } } /** * Start the watch. */ public void start() { start(false); } /** * Stop the watch. * * @return Elapsed time or 0 if the watch was never started. */ public long stop() { long lap = 0; if (running) { count++; stop = System.currentTimeMillis(); lap = stop - start; total += lap; running = false; } return lap; } /** * Reset the watch. */ public void reset() { start = -1; stop = -1; total = 0; count = 0; running = false; } /** * Get the <i>lap</i> count. * * @return The <i>lap</i> count. */ public int getLapCount() { return count; } /** * Get the elapsed <i>lap</i> time since the watch was started. * * @return Elapsed <i>lap</i> time or 0 if the watch was never started */ public long getLapTime() { if (start == -1) { return 0; } else if (running) { return System.currentTimeMillis() - start; } else { return stop - start; } } /** * Get the average <i>lap</i> time since the watch was started. * * @return Average <i>lap</i> time since the watch was started. */ public long getAverageLapTime() { return (count == 0) ? 0 : getLapTime() / getLapCount(); } /** * Get the elapsed time since the watch was created or last reset. * * @return Elapsed time or 0 if the watch was never started. */ public long getTime() { if (start == -1) { return 0; } else if (running) { return total + System.currentTimeMillis() - start; } else { return total; } } /** * Check if the watch is running. * * @return True if the watch is running. */ public boolean isRunning() { return running; } /** * Return a string representation. */ public String toString() { StringBuffer buff = new StringBuffer(); if (running) { // the watch has not been stopped formatElapsedTime(buff, getTime()); // add the current lap time too if there is more than one lap if (count >= 1) { buff.append(", count=").append(count); buff.append(", current="); formatElapsedTime(buff, getLapTime()); } } else { // the watch has been stopped formatElapsedTime(buff, getTime()); // add extra info if there is more than one lap if (count > 1) { buff.append(", count=").append(count); buff.append(", average="); formatElapsedTime(buff, getAverageLapTime()); } } return buff.toString(); } private void formatElapsedTime(final StringBuffer buff, final long lapsed) { long m = lapsed / 60000; if (m != 0) { buff.append(m).append("m:"); } long s = (lapsed - 60000 * m) / 1000; if (s != 0) { buff.append(s).append("s:"); } // ms is always there, even if it was 0 too long ms = (lapsed - 60000 * m - 1000 * s); buff.append(ms).append("ms"); } /** * Return a cloned copy of this object. * * @return A cloned copy of this object. */ public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { throw new InternalError(); } } // /////////////////////////////////////////////////////////////////////// // Wrappers // // /////////////////////////////////////////////////////////////////////// /** * Base wrapper class for other wrappers. */ private static class Wrapper extends StopWatch { /** The serialVersionUID */ private static final long serialVersionUID = 6859401939735540773L; protected StopWatch watch; public Wrapper(final StopWatch watch) { this.watch = watch; } public void start(final boolean reset) { watch.start(reset); } public void start() { watch.start(); } public long stop() { return watch.stop(); } public void reset() { watch.reset(); } public long getLapTime() { return watch.getLapTime(); } public long getAverageLapTime() { return watch.getAverageLapTime(); } public int getLapCount() { return watch.getLapCount(); } public long getTime() { return watch.getTime(); } public boolean isRunning() { return watch.isRunning(); } public String toString() { return watch.toString(); } } /** * Return a synchronized stop watch. * * @param watch * StopWatch to synchronize. * @return Synchronized stop watch. */ public static StopWatch makeSynchronized(final StopWatch watch) { return new Wrapper(watch) { /** The serialVersionUID */ private static final long serialVersionUID = -6284244000894114817L; public synchronized void start(final boolean reset) { this.watch.start(reset); } public synchronized void start() { this.watch.start(); } public synchronized long stop() { return this.watch.stop(); } public synchronized void reset() { this.watch.reset(); } public synchronized long getLapTime() { return this.watch.getLapTime(); } public synchronized long getAverageLapTime() { return this.watch.getAverageLapTime(); } public synchronized int getLapCount() { return this.watch.getLapCount(); } public synchronized long getTime() { return this.watch.getTime(); } public synchronized boolean isRunning() { return this.watch.isRunning(); } public synchronized String toString() { return this.watch.toString(); } }; } }