public final class Stopwatch
extends java.lang.Object
In contrast, wall time is a reading of "now" as given by a method like
System.currentTimeMillis()
, best represented as an Instant
. Such values
can be subtracted to obtain a Duration
(such as by Duration.between
), but
doing so does not give a reliable measurement of elapsed time, because wall time readings
are inherently approximate, routinely affected by periodic clock corrections. Because this class
(by default) uses System.nanoTime()
, it is unaffected by these changes.
Use this class instead of direct calls to System.nanoTime()
for two reasons:
long
values returned by nanoTime
are meaningless and unsafe to use
in any other way than how Stopwatch
uses them.
Basic usage:
Stopwatch stopwatch = Stopwatch.createStarted();
doSomething();
stopwatch.stop(); // optional
Duration duration = stopwatch.elapsed();
log.info("time: " + stopwatch); // formatted string like "12.3 ms"
The state-changing methods are not idempotent; it is an error to start or stop a stopwatch that is already in the desired state.
When testing code that uses this class, use createUnstarted(Ticker)
or createStarted(Ticker)
to supply a fake or mock ticker. This allows you to simulate any valid
behavior of the stopwatch.
Note: This class is not thread-safe.
Warning for Android users: a stopwatch with default behavior may not continue to keep time while the device is asleep. Instead, create one like this:
Stopwatch.createStarted(
new Ticker() {
public long read() {
return android.os.SystemClock.elapsedRealtimeNanos();
}
});
Modifier and Type | Field and Description |
---|---|
private long |
elapsedNanos |
private boolean |
isRunning |
private long |
startTick |
private Ticker |
ticker |
Modifier and Type | Method and Description |
---|---|
private static java.lang.String |
abbreviate(java.util.concurrent.TimeUnit unit) |
private static java.util.concurrent.TimeUnit |
chooseUnit(long nanos) |
static Stopwatch |
createStarted()
Creates (and starts) a new stopwatch using
System.nanoTime() as its time source. |
static Stopwatch |
createStarted(Ticker ticker)
Creates (and starts) a new stopwatch, using the specified time source.
|
static Stopwatch |
createUnstarted()
Creates (but does not start) a new stopwatch using
System.nanoTime() as its time source. |
static Stopwatch |
createUnstarted(Ticker ticker)
Creates (but does not start) a new stopwatch, using the specified time source.
|
java.time.Duration |
elapsed()
Returns the current elapsed time shown on this stopwatch as a
Duration . |
long |
elapsed(java.util.concurrent.TimeUnit desiredUnit)
Returns the current elapsed time shown on this stopwatch, expressed in the desired time unit,
with any fraction rounded down.
|
private long |
elapsedNanos() |
boolean |
isRunning()
|
Stopwatch |
reset()
Sets the elapsed time for this stopwatch to zero, and places it in a stopped state.
|
Stopwatch |
start()
Starts the stopwatch.
|
Stopwatch |
stop()
Stops the stopwatch.
|
java.lang.String |
toString()
Returns a string representation of the current elapsed time.
|
private final Ticker ticker
private boolean isRunning
private long elapsedNanos
private long startTick
Stopwatch()
Stopwatch(Ticker ticker)
public static Stopwatch createUnstarted()
System.nanoTime()
as its time source.public static Stopwatch createUnstarted(Ticker ticker)
public static Stopwatch createStarted()
System.nanoTime()
as its time source.public static Stopwatch createStarted(Ticker ticker)
public boolean isRunning()
public Stopwatch start()
Stopwatch
instancejava.lang.IllegalStateException
- if the stopwatch is already running.public Stopwatch stop()
Stopwatch
instancejava.lang.IllegalStateException
- if the stopwatch is already stopped.public Stopwatch reset()
Stopwatch
instanceprivate long elapsedNanos()
public long elapsed(java.util.concurrent.TimeUnit desiredUnit)
Note: the overhead of measurement can be more than a microsecond, so it is generally
not useful to specify TimeUnit.NANOSECONDS
precision here.
It is generally not a good idea to use an ambiguous, unitless long
to represent
elapsed time. Therefore, we recommend using elapsed()
instead, which returns a
strongly-typed Duration
instance.
elapsedTime()
)public java.time.Duration elapsed()
Duration
. Unlike elapsed(TimeUnit)
, this method does not lose any precision due to rounding.public java.lang.String toString()
toString
in class java.lang.Object
private static java.util.concurrent.TimeUnit chooseUnit(long nanos)
private static java.lang.String abbreviate(java.util.concurrent.TimeUnit unit)