/** * Get a {@link CachedScheduler} out of the {@code reference} or create one using the * {@link Supplier} if the reference is empty, effectively creating a single instance * to be reused as a default scheduler for the given {@code key} category. * * @param reference the cache reference that holds the scheduler * @param key the "name" for the Scheduler's category/type * @param supplier the {@link Scheduler} generator to use and wrap into a {@link CachedScheduler}. * Note that in case of a race, an extraneous Scheduler can be created, but it'll get * immediately {@link Scheduler#dispose() disposed}. * @return a {@link CachedScheduler} to be reused, either pre-existing or created */ static CachedScheduler cache(AtomicReference<CachedScheduler> reference, String key, Supplier<Scheduler> supplier) { CachedScheduler s = reference.get(); if (s != null) { return s; } s = new CachedScheduler(key, supplier.get()); if (reference.compareAndSet(null, s)) { return s; } //the reference was updated in the meantime with a cached scheduler //fallback to it and dispose the extraneous one s._dispose(); return reference.get(); }
/** * Get a {@link CachedScheduler} out of the {@code reference} or create one using the * {@link Supplier} if the reference is empty, effectively creating a single instance * to be reused as a default scheduler for the given {@code key} category. * * @param reference the cache reference that holds the scheduler * @param key the "name" for the Scheduler's category/type * @param supplier the {@link Scheduler} generator to use and wrap into a {@link CachedScheduler}. * Note that in case of a race, an extraneous Scheduler can be created, but it'll get * immediately {@link Scheduler#dispose() disposed}. * @return a {@link CachedScheduler} to be reused, either pre-existing or created */ static CachedScheduler cache(AtomicReference<CachedScheduler> reference, String key, Supplier<Scheduler> supplier) { CachedScheduler s = reference.get(); if (s != null) { return s; } s = new CachedScheduler(key, supplier.get()); if (reference.compareAndSet(null, s)) { return s; } //the reference was updated in the meantime with a cached scheduler //fallback to it and dispose the extraneous one s._dispose(); return reference.get(); }
/** * Clear any cached {@link Scheduler} and call dispose on them. */ public static void shutdownNow() { CachedScheduler oldElastic = CACHED_ELASTIC.getAndSet(null); CachedScheduler oldParallel = CACHED_PARALLEL.getAndSet(null); CachedScheduler oldSingle = CACHED_SINGLE.getAndSet(null); if (oldElastic != null) oldElastic._dispose(); if (oldParallel != null) oldParallel._dispose(); if (oldSingle != null) oldSingle._dispose(); }
Schedulers.CachedScheduler cached = new Schedulers.CachedScheduler("cached", mock); cached.dispose(); cached.dispose(); .isThrownBy(() -> cached.schedule(null)) .withMessage("scheduleTask"); .isThrownBy(() -> cached.schedule(null, 1000, TimeUnit.MILLISECONDS)) .withMessage("scheduleTaskDelay"); .isThrownBy(() -> cached.schedulePeriodically(null, 1000, 1000, TimeUnit.MILLISECONDS)) .withMessage("schedulePeriodically"); .isThrownBy(() -> cached.now(TimeUnit.MILLISECONDS)) .withMessage("now");
/** * Clear any cached {@link Scheduler} and call dispose on them. */ public static void shutdownNow() { CachedScheduler oldElastic = CACHED_ELASTIC.getAndSet(null); CachedScheduler oldParallel = CACHED_PARALLEL.getAndSet(null); CachedScheduler oldSingle = CACHED_SINGLE.getAndSet(null); if (oldElastic != null) oldElastic._dispose(); if (oldParallel != null) oldParallel._dispose(); if (oldSingle != null) oldSingle._dispose(); }