SingleThreadColocationLogger implements ColocationLogger { @Override public ColocationLogger start() { synchronized (lock) { if (completed.get() != null) { throw new IllegalStateException(this + " is already running"); } completed.set(executorService.submit(checkForMissingColocatedRegionRunnable())); return this; } } SingleThreadColocationLogger(PartitionedRegion region, long delayMillis, long intervalMillis); @VisibleForTesting  SingleThreadColocationLogger(PartitionedRegion region, long delayMillis,
      long intervalMillis, Consumer<String> logger,
      Function<PartitionedRegion, Set<String>> allColocationRegionsProvider,
      ExecutorService executorService); @Override ColocationLogger start(); @Override void stop(); @Override void addMissingChildRegion(String childFullPath); @Override void addMissingChildRegions(PartitionedRegion childRegion); @Override List<String> updateAndGetMissingChildRegions(); @Override String toString();  }
@Test public void startWhenAlreadyRunningThrowsIllegalStateException() { SingleThreadColocationLogger colocationLogger = new SingleThreadColocationLogger(region, 500, 1000, logger, allColocationRegionsProvider, executorService); colocationLogger.start(); Throwable thrown = catchThrowable(() -> colocationLogger.start()); assertThat(thrown) .isInstanceOf(IllegalStateException.class) .hasMessage("ColocationLogger for " + regionName + " is already running"); }