True, though in the comment we explicitly mention we do not check that start or stop are called correctly. The main use-case for this change is that some users want to track the duration of something wrapped in a timer while it is running. An example:

{code}
Stopwatch s = timer.start();
while (!done) {
  ... do something ...
  logger.debug("something is in progress, duration {}ms", s.getDuration(TimeUnit.MILLISECONDS));
}
s.stop();
{code} 

The running flag is to guard against the likely rare event that endTime is actually set to 0 when stop is called. This change maintains the previous behavior other than making the value of getDuration meaningful after start is called where before is was only meaningful after both start and stop were called.

Throwing an exception will cause user code to break at runtime if they were using the stopwatch incorrectly. That might be ok, but we have had complaints about similar behavior in the past as it led to a more serious outage than just having a bad value for the timer and I don't want to introduce such a behavior without more discussion. In general, this is something where we have found many users tend to expect the monitoring calls to behave similar to logging calls and think they should never throw.