/**
* A simple Stopwatch utility for measuring time in milliseconds.
*
* @author Stefan Nilsson
* @version 2010-03-10
*/
public class Stopwatch {
/**
* Time when start() was called. Contains a valid time
* only if the clock is running.
*/
private long startTime;
/**
* Holds the total accumulated time since last reset.
* Does not include time since start() if clock is running.
*/
private long totalTime = 0;
private boolean isRunning = false;
/**
* Constructs a new Stopwatch. The new clock is not
* running and the total time is set to 0.
*/
public Stopwatch() {}
/**
* Turns this clock on.
* Has no effect if the clock is already running.
*
* @return a reference to this Stopwatch.
*/
public Stopwatch start() {
if (!isRunning) {
isRunning = true;
startTime = System.nanoTime();
}
return this;
}
/**
* Turns this clock off.
* Has no effect if the clock is not running.
*
* @return a reference to this Stopwatch.
*/
public Stopwatch stop() {
if (isRunning) {
totalTime += System.nanoTime() - startTime;
isRunning = false;
}
return this;
}
/**
* Resets this clock.
* The clock is stopped and the total time is set to 0.
*
* @return a reference to this Stopwatch.
*/
public Stopwatch reset() {
isRunning = false;
totalTime = 0;
return this;
}
/**
* Returns the total time that this clock has been running since
* last reset.
* Does not affect the running status of the clock; if the clock
* is running when this method is called, it continues to run.
*
* @return the time in milliseconds.
*/
public long getTime() {
return getTimeNano() / 1000000;
}
private long getTimeNano() {
return totalTime +
(isRunning ? System.nanoTime() - startTime : 0);
}
/**
* Tests if this clock is running.
*
* @return true
if this clock is running;
* false
otherwise.
*/
public boolean isRunning() {
return isRunning;
}
/**
* Returns a string description of this clock. The exact details
* of the representation are unspecified and subject to change,
* but this is typical: "25 ms (running)".
*/
@Override
public String toString() {
return getTime() + " ms" +
(isRunning() ? " (running)" : " (not running)");
}
/**
* Unit test. Run with java -ea Stopwatch
.
*/
public static void main(String[] args) throws InterruptedException {
Stopwatch c = new Stopwatch();
assert !c.isRunning();
assert c.getTime() == 0;
assert c.toString().equals("0 ms (not running)");
c.stop();
assert !c.isRunning();
assert c.getTime() == 0;
c.reset();
assert !c.isRunning();
assert c.getTime() == 0;
c.start();
String s = c.toString();
assert s.equals("0 ms (running)") || s.equals("1 ms (running)");
assert c.isRunning();
c.stop();
assert !c.isRunning();
c.start();
assert c.isRunning();
c.reset();
assert !c.isRunning();
assert c.getTime() == 0;
c.start();
assert c.getTime() < 2;
assert c.isRunning();
Thread.sleep(2);
assert c.isRunning();
assert c.getTime() > 0;
assert c.getTime() < 4;
assert !c.toString().equals("0 ms (running)");
Thread.sleep(10);
assert c.isRunning();
assert c.getTime() > 10;
assert c.getTime() < 14;
c.stop();
assert !c.isRunning();
assert c.getTime() > 10;
assert c.getTime() < 14;
c.stop();
assert !c.isRunning();
assert c.getTime() > 10;
assert c.getTime() < 14;
c.start();
assert c.isRunning();
assert c.getTime() > 10;
assert c.getTime() < 14;
Thread.sleep(10);
assert c.isRunning();
assert c.getTime() > 20;
assert c.getTime() < 24;
c.reset();
assert !c.isRunning();
assert c.getTime() == 0;
assert c.toString().equals("0 ms (not running)");
}
}