I did relax this somewhat in that calling start() without stop() or dead threads will now be cleared away. There is a degree of robustness. However the MUST emphasis remains because sloppy code that does not call stop will potentially leave ActivityTimeMonitor with the volatile boolean in error state meaning timeout checks have to do more work than necessary for what is really an non-error state.