io.reactivex.rxjava3.internal.schedulers.SingleScheduler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of redisson-all Show documentation
Show all versions of redisson-all Show documentation
Easy Redis Java client and Real-Time Data Platform. Valkey compatible. Sync/Async/RxJava3/Reactive API. Client side caching. Over 50 Redis based Java objects and services: JCache API, Apache Tomcat, Hibernate, Spring, Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Bloom filter, Scheduler, RPC
/*
* Copyright (c) 2016-present, RxJava Contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
* the License for the specific language governing permissions and limitations under the License.
*/
package io.reactivex.rxjava3.internal.schedulers;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Scheduler;
import io.reactivex.rxjava3.disposables.*;
import io.reactivex.rxjava3.internal.disposables.EmptyDisposable;
import io.reactivex.rxjava3.plugins.RxJavaPlugins;
/**
* A scheduler with a shared, single threaded underlying ScheduledExecutorService.
* @since 2.0
*/
public final class SingleScheduler extends Scheduler {
final ThreadFactory threadFactory;
final AtomicReference executor = new AtomicReference<>();
/** The name of the system property for setting the thread priority for this Scheduler. */
private static final String KEY_SINGLE_PRIORITY = "rx3.single-priority";
private static final String THREAD_NAME_PREFIX = "RxSingleScheduler";
static final RxThreadFactory SINGLE_THREAD_FACTORY;
static final ScheduledExecutorService SHUTDOWN;
static {
SHUTDOWN = Executors.newScheduledThreadPool(0);
SHUTDOWN.shutdown();
int priority = Math.max(Thread.MIN_PRIORITY, Math.min(Thread.MAX_PRIORITY,
Integer.getInteger(KEY_SINGLE_PRIORITY, Thread.NORM_PRIORITY)));
SINGLE_THREAD_FACTORY = new RxThreadFactory(THREAD_NAME_PREFIX, priority, true);
}
public SingleScheduler() {
this(SINGLE_THREAD_FACTORY);
}
/**
* Constructs a SingleScheduler with the given ThreadFactory and prepares the
* single scheduler thread.
* @param threadFactory thread factory to use for creating worker threads. Note that this takes precedence over any
* system properties for configuring new thread creation. Cannot be null.
*/
public SingleScheduler(ThreadFactory threadFactory) {
this.threadFactory = threadFactory;
executor.lazySet(createExecutor(threadFactory));
}
static ScheduledExecutorService createExecutor(ThreadFactory threadFactory) {
return SchedulerPoolFactory.create(threadFactory);
}
@Override
public void start() {
ScheduledExecutorService next = null;
for (;;) {
ScheduledExecutorService current = executor.get();
if (current != SHUTDOWN) {
if (next != null) {
next.shutdown();
}
return;
}
if (next == null) {
next = createExecutor(threadFactory);
}
if (executor.compareAndSet(current, next)) {
return;
}
}
}
@Override
public void shutdown() {
ScheduledExecutorService current = executor.getAndSet(SHUTDOWN);
if (current != SHUTDOWN) {
current.shutdownNow();
}
}
@NonNull
@Override
public Worker createWorker() {
return new ScheduledWorker(executor.get());
}
@NonNull
@Override
public Disposable scheduleDirect(@NonNull Runnable run, long delay, TimeUnit unit) {
ScheduledDirectTask task = new ScheduledDirectTask(RxJavaPlugins.onSchedule(run), true);
try {
Future> f;
if (delay <= 0L) {
f = executor.get().submit(task);
} else {
f = executor.get().schedule(task, delay, unit);
}
task.setFuture(f);
return task;
} catch (RejectedExecutionException ex) {
RxJavaPlugins.onError(ex);
return EmptyDisposable.INSTANCE;
}
}
@NonNull
@Override
public Disposable schedulePeriodicallyDirect(@NonNull Runnable run, long initialDelay, long period, TimeUnit unit) {
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
if (period <= 0L) {
ScheduledExecutorService exec = executor.get();
InstantPeriodicTask periodicWrapper = new InstantPeriodicTask(decoratedRun, exec);
Future> f;
try {
if (initialDelay <= 0L) {
f = exec.submit(periodicWrapper);
} else {
f = exec.schedule(periodicWrapper, initialDelay, unit);
}
periodicWrapper.setFirst(f);
} catch (RejectedExecutionException ex) {
RxJavaPlugins.onError(ex);
return EmptyDisposable.INSTANCE;
}
return periodicWrapper;
}
ScheduledDirectPeriodicTask task = new ScheduledDirectPeriodicTask(decoratedRun, true);
try {
Future> f = executor.get().scheduleAtFixedRate(task, initialDelay, period, unit);
task.setFuture(f);
return task;
} catch (RejectedExecutionException ex) {
RxJavaPlugins.onError(ex);
return EmptyDisposable.INSTANCE;
}
}
static final class ScheduledWorker extends Scheduler.Worker {
final ScheduledExecutorService executor;
final CompositeDisposable tasks;
volatile boolean disposed;
ScheduledWorker(ScheduledExecutorService executor) {
this.executor = executor;
this.tasks = new CompositeDisposable();
}
@NonNull
@Override
public Disposable schedule(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
if (disposed) {
return EmptyDisposable.INSTANCE;
}
Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, tasks);
tasks.add(sr);
try {
Future> f;
if (delay <= 0L) {
f = executor.submit((Callable
© 2015 - 2024 Weber Informatics LLC | Privacy Policy