@Override public void run() { try { LOG.info(getName() + " thread started"); if (!compareAndSetState( FileChangeWatcher.State.STARTING, FileChangeWatcher.State.RUNNING)) { // stop() called shortly after start(), before // this thread started running. FileChangeWatcher.State state = FileChangeWatcher.this.getState(); if (state != FileChangeWatcher.State.STOPPING) { throw new IllegalStateException("Unexpected state: " + state); } return; } runLoop(); } catch (Exception e) { LOG.warn("Error in runLoop()", e); throw e; } finally { try { watchService.close(); } catch (IOException e) { LOG.warn("Error closing watch service", e); } LOG.info(getName() + " thread finished"); FileChangeWatcher.this.setState(FileChangeWatcher.State.STOPPED); } }