/** * Shuts down the scheduler and calls the close method in the RefreshingLoader. * Allows the user to demand immediate shutdown; this should only be used for testing. * * @param closeNow Will shut down immediately if this is true, otherwise will attempt to wait * for concurrent execution. * @throws IOException If the RefreshingLoader encounters an error on closing. */ public void close( Boolean closeNow ) throws IOException { try { if (closeNow) { mScheduler.shutdownNow(); mRefreshingLoader.close(); } else { mScheduler.shutdown(); // Await termination so that we don't close the state out from under the function mScheduler.awaitTermination(10, TimeUnit.SECONDS); mRefreshingLoader.close(); } } catch (InterruptedException e) { Thread.interrupted(); mRefreshingLoader.close(); } finally { ResourceTracker.get().unregisterResource(this); } }
/** * Private constructor. * * @param refreshPeriod Configures the refresh rate for the scheduler. * @param timeUnit Specifies the unit of time for the refreshPeriod. * @param refreshingLoader Used to initialize and refresh the cached value. * @param builder Thread factory builder. Expects that the name format is already set. * @param loopController Used to deterministically control refresh cycles during testing. */ private RefreshingReference( final Long refreshPeriod, final TimeUnit timeUnit, final RefreshingLoader<T> refreshingLoader, final ThreadFactoryBuilder builder, final Optional<LoopController> loopController ) { mRef = new AtomicReference<>(WithTimestamp.create(refreshingLoader.initial())); mScheduler = Executors.newSingleThreadScheduledExecutor( builder .setDaemon(true) .build() ); mRefreshingLoader = refreshingLoader; final RefreshingRunnable runnable = new RefreshingRunnable(); mScheduler.scheduleAtFixedRate(runnable, refreshPeriod, refreshPeriod, timeUnit); mLoopController = loopController; ResourceTracker.get().registerResource(this); }