Scheduler is an object that specifies an API for scheduling
units of work provided in the form of Runnables to be
executed without delay (effectively as soon as possible), after a specified time delay or periodically
and represents an abstraction over an asynchronous boundary that ensures
these units of work get executed by some underlying task-execution scheme
(such as custom Threads, event loop, Executor or Actor system)
with some uniform properties and guarantees regardless of the particular underlying
scheme.
You can get various standard, RxJava-specific instances of this class via
the static methods of the io. utility class.
The so-called Workers of a Scheduler can be created via the createWorker() method which allow the scheduling
of multiple Runnable tasks in an isolated manner. Runnable tasks scheduled on a Worker are guaranteed to be
executed sequentially and in a non-overlapping fashion. Non-delayed Runnable tasks are guaranteed to execute in a
First-In-First-Out order but their execution may be interleaved with delayed tasks.
In addition, outstanding or running tasks can be cancelled together via
Worker#dispose() without affecting any other Worker instances of the same Scheduler.
Implementations of the scheduleDirect and Worker#schedule methods are encouraged to call the io.
method to allow a scheduler hook to manipulate (wrap or replace) the original Runnable task before it is submitted to the
underlying task-execution scheme.
The default implementations of the scheduleDirect methods provided by this abstract class
delegate to the respective schedule methods in the Worker instance created via createWorker()
for each individual Runnable task submitted. Implementors of this class are encouraged to provide
a more efficient direct scheduling implementation to avoid the time and memory overhead of creating such Workers
for every task.
This delegation is done via special wrapper instances around the original Runnable before calling the respective
Worker.schedule method. Note that this can lead to multiple RxJavaPlugins.onSchedule calls and potentially
multiple hooks applied. Therefore, the default implementations of scheduleDirect (and the Worker#schedulePeriodically(Runnable, long, long, TimeUnit))
wrap the incoming Runnable into a class that implements the io.
interface which can grant access to the original or hooked Runnable, thus, a repeated RxJavaPlugins.onSchedule
can detect the earlier hook and not apply a new one over again.
The default implementation of now(TimeUnit) and Worker#now(TimeUnit) methods to return current System#currentTimeMillis()
value in the desired time unit, unless rx2.scheduler.use-nanotime (boolean) is set. When the property is set to
true, the method uses System#nanoTime() as its basis instead. Custom Scheduler implementations can override this
to provide specialized time accounting (such as virtual time to be advanced programmatically).
Note that operators requiring a Scheduler may rely on either of the now() calls provided by
Scheduler or Worker respectively, therefore, it is recommended they represent a logically
consistent source of the current time.
The default implementation of the Worker#schedulePeriodically(Runnable, long, long, TimeUnit) method uses
the Worker#schedule(Runnable, long, TimeUnit) for scheduling the Runnable task periodically.
The algorithm calculates the next absolute time when the task should run again and schedules this execution
based on the relative time between it and Worker#now(TimeUnit). However, drifts or changes in the
system clock could affect this calculation either by scheduling subsequent runs too frequently or too far apart.
Therefore, the default implementation uses the clockDriftTolerance() value (set via
rx2.scheduler.drift-tolerance in minutes) to detect a drift in Worker#now(TimeUnit) and
re-adjust the absolute/relative time calculation accordingly.
The default implementations of start() and shutdown() do nothing and should be overridden if the
underlying task-execution scheme supports stopping and restarting itself.
If the Scheduler is shut down or a Worker is disposed, the schedule methods
should return the io. singleton instance indicating the shut down/disposed
state to the caller. Since the shutdown or dispose can happen from any thread, the schedule implementations
should make best effort to cancel tasks immediately after those tasks have been submitted to the
underlying task-execution scheme if the shutdown/dispose was detected after this submission.
All methods on the Scheduler and Worker classes should be thread safe.
| Modifier and Type | Class and Description |
|---|---|
| pack-priv static class | |
| pack-priv static class | |
| public abstract static class | Scheduler.Worker
Represents an isolated, sequential worker of a parent Scheduler for executing |
| Modifier and Type | Field and Description |
|---|---|
| pack-priv static final long | CLOCK_DRIFT_TOLERANCE_NANOSECONDS
The tolerance for a clock drift in nanoseconds where the periodic scheduler will rebase. |
| pack-priv static boolean | IS_DRIFT_USE_NANOTIME
Value representing whether to use Associated system parameter:
|
| Access | Constructor and Description |
|---|---|
| public |
| Modifier and Type | Method and Description |
|---|---|
| public static long | Returns: the tolerance in nanosecondsReturns the clock drift tolerance in nanoseconds. |
| pack-priv static long | Returns: the 'current time' in given unitthe time unit unit)Returns the current clock time depending on state of
By default |
| public abstract Scheduler. | Returns: a Worker representing a serial queue of actions to be executedRetrieves or creates a new |
| public long | |
| public Disposable | Returns: the Disposable instance that let's one cancel this particular task.the task to execute run)Schedules the given task on this Scheduler without any time delay. |
| public Disposable | Returns: the Disposable that let's one cancel this particular delayed task.the task to schedule run, long the delay amount, non-positive values indicate non-delayed scheduling delay, TimeUnit the unit of measure of the delay amount unit)Schedules the execution of the given task with the given time delay. |
| public Disposable | Returns: the Disposable that let's one cancel this particular delayed task.the task to schedule run, long the initial delay amount, non-positive values indicate non-delayed scheduling initialDelay, long the period at which the task should be re-executed period, TimeUnit the unit of measure of the delay amount unit)Schedules a periodic execution of the given task with the given initial time delay and repeat period. |
| public void | |
| public void | |
| public < a Scheduler and a Subscription S extends Scheduler & Disposable> S | Returns: the Scheduler with the customized execution behaviorthe function that takes a two-level nested Flowable sequence of a Completable and returns
the Completable that will be subscribed to and should trigger the execution of the scheduled Actions. combine)Allows the use of operators for controlling the timing around when actions scheduled on workers are actually done. |
| CLOCK_DRIFT_TOLERANCE_NANOSECONDS | back to summary |
|---|---|
| pack-priv static final long CLOCK_DRIFT_TOLERANCE_NANOSECONDS The tolerance for a clock drift in nanoseconds where the periodic scheduler will rebase.
The associated system parameter, | |
| IS_DRIFT_USE_NANOTIME | back to summary |
|---|---|
| pack-priv static boolean IS_DRIFT_USE_NANOTIME Value representing whether to use Associated system parameter:
| |
| Scheduler | back to summary |
|---|---|
| public Scheduler() | |
| clockDriftTolerance | back to summary |
|---|---|
| public static long clockDriftTolerance() Returns the clock drift tolerance in nanoseconds. Related system property:
| |
| computeNow | back to summary |
|---|---|
| pack-priv static long computeNow(TimeUnit unit) Returns the current clock time depending on state of
By default
| |
| createWorker | back to summary |
|---|---|
| public abstract Scheduler. Retrieves or creates a new
When work is completed, the
Work on a | |
| now | back to summary |
|---|---|
| public long now(TimeUnit unit) Returns the 'current time' of the Scheduler in the specified time unit.
| |
| scheduleDirect | back to summary |
|---|---|
| public Disposable scheduleDirect(Runnable run) Schedules the given task on this Scheduler without any time delay. This method is safe to be called from multiple threads but there are no ordering or non-overlapping guarantees between tasks.
| |
| scheduleDirect | back to summary |
|---|---|
| public Disposable scheduleDirect(Runnable run, long delay, TimeUnit unit) Schedules the execution of the given task with the given time delay. This method is safe to be called from multiple threads but there are no ordering guarantees between tasks.
| |
| schedulePeriodicallyDirect | back to summary |
|---|---|
| public Disposable schedulePeriodicallyDirect(Runnable run, long initialDelay, long period, TimeUnit unit) Schedules a periodic execution of the given task with the given initial time delay and repeat period. This method is safe to be called from multiple threads but there are no ordering guarantees between tasks.
The periodic execution is at a fixed rate, that is, the first execution will be after the
| |
| shutdown | back to summary |
|---|---|
| public void shutdown() Instructs the Scheduler instance to stop threads,
stop accepting tasks on any outstanding
Implementations should make sure the call is idempotent, thread-safe and
should not throw any
| |
| start | back to summary |
|---|---|
| public void start() Allows the Scheduler instance to start threads and accept tasks on them.
Implementations should make sure the call is idempotent, thread-safe and
should not throw any
| |
| when | back to summary |
|---|---|
| public <S extends Scheduler & Disposable> S when(Function<Flowable<Flowable<Completable>>, Completable> combine) Allows the use of operators for controlling the timing around when
actions scheduled on workers are actually done. This makes it possible to
layer additional behavior on this
When
Finally the actions scheduled on the parent
When the Limit the amount concurrency two at a time without creating a new fix size thread pool:
Scheduler limitScheduler = Schedulers.computation().when(workers -> {
// use merge max concurrent to limit the number of concurrent
// callbacks two at a time
return Completable.merge(Flowable.merge(workers), 2);
});
This is a slightly different way to limit the concurrency but it has some
interesting benefits and drawbacks to the method above. It works by
limited the number of concurrent
Scheduler limitScheduler = Schedulers.computation().when(workers -> {
// use merge max concurrent to limit the number of concurrent
// Flowables two at a time
return Completable.merge(Flowable.merge(workers, 2));
});
Slowing down the rate to no more than than 1 a second. This suffers from
the same problem as the one above I could find an Flowable
operator that limits the rate without dropping the values (aka leaky
bucket algorithm).
Scheduler slowScheduler = Schedulers.computation().when(workers -> {
// use concatenate to make each worker happen one at a time.
return Completable.concat(workers.map(actions -> {
// delay the starting of the next worker by 1 second.
return Completable.merge(actions.delaySubscription(1, TimeUnit.SECONDS));
}));
});
History: 2.0.1 - experimental
| |
| Modifier and Type | Field and Description |
|---|---|
| pack-priv final Runnable | |
| pack-priv Thread | |
| pack-priv final Scheduler. |
| Access | Constructor and Description |
|---|---|
| pack-priv |
| Modifier and Type | Method and Description |
|---|---|
| public void | dispose()
Implements io. |
| public Runnable | getWrappedRunnable()
Implements io. |
| public boolean | isDisposed()
Implements io. |
| public void |
| decoratedRun | back to summary |
|---|---|
| pack-priv final Runnable decoratedRun
| |
| runner | back to summary |
|---|---|
| pack-priv Thread runner
| |
| w | back to summary |
|---|---|
| pack-priv final Scheduler. | |
| DisposeTask | back to summary |
|---|---|
| pack-priv DisposeTask(Runnable decoratedRun, Scheduler. | |
| dispose | back to summary |
|---|---|
| public void dispose() Implements io. Doc from io. Dispose the resource, the operation should be idempotent.
| |
| getWrappedRunnable | back to summary |
|---|---|
| public Runnable getWrappedRunnable() Implements io. Doc from io. Returns the wrapped action. | |
| isDisposed | back to summary |
|---|---|
| public boolean isDisposed() Implements io. Doc from io. Returns true if this resource has been disposed.
| |
| run | back to summary |
|---|---|
| public void run() Implements java. Doc from java. Runs this operation.
| |
| Modifier and Type | Field and Description |
|---|---|
| pack-priv volatile boolean | |
| pack-priv final Runnable | |
| pack-priv final Scheduler. |
| Access | Constructor and Description |
|---|---|
| pack-priv |
| Modifier and Type | Method and Description |
|---|---|
| public void | dispose()
Implements io. |
| public Runnable | getWrappedRunnable()
Implements io. |
| public boolean | isDisposed()
Implements io. |
| public void |
| disposed | back to summary |
|---|---|
| pack-priv volatile boolean disposed | |
| run | back to summary |
|---|---|
| pack-priv final Runnable run
| |
| worker | back to summary |
|---|---|
| pack-priv final Scheduler. | |
| PeriodicDirectTask | back to summary |
|---|---|
| pack-priv PeriodicDirectTask(Runnable run, Scheduler. | |
| dispose | back to summary |
|---|---|
| public void dispose() Implements io. Doc from io. Dispose the resource, the operation should be idempotent.
| |
| getWrappedRunnable | back to summary |
|---|---|
| public Runnable getWrappedRunnable() Implements io. Doc from io. Returns the wrapped action. | |
| isDisposed | back to summary |
|---|---|
| public boolean isDisposed() Implements io. Doc from io. Returns true if this resource has been disposed.
| |
| run | back to summary |
|---|---|
| public void run() Implements java. Doc from java. Runs this operation.
| |
Runnable tasks on
an underlying task-execution scheme (such as custom Threads, event loop, Executor or Actor system).
Disposing the Worker should cancel all outstanding work and allows resource cleanup.
The default implementations of schedule(Runnable) and schedulePeriodically(Runnable, long, long, TimeUnit)
delegate to the abstract schedule(Runnable, long, TimeUnit) method. Its implementation is encouraged to
track the individual Runnable tasks while they are waiting to be executed (with or without delay) so that
dispose() can prevent their execution or potentially interrupt them if they are currently running.
The default implementation of the now(TimeUnit) method returns current System#currentTimeMillis()
value in the desired time unit, unless rx2.scheduler.use-nanotime (boolean) is set. When the property is set to
true, the method uses System#nanoTime() as its basis instead. Custom Worker implementations can override this
to provide specialized time accounting (such as virtual time to be advanced programmatically).
Note that operators requiring a scheduler may rely on either of the now() calls provided by
Scheduler or Worker respectively, therefore, it is recommended they represent a logically
consistent source of the current time.
The default implementation of the schedulePeriodically(Runnable, long, long, TimeUnit) method uses
the schedule(Runnable, long, TimeUnit) for scheduling the Runnable task periodically.
The algorithm calculates the next absolute time when the task should run again and schedules this execution
based on the relative time between it and now(TimeUnit). However, drifts or changes in the
system clock would affect this calculation either by scheduling subsequent runs too frequently or too far apart.
Therefore, the default implementation uses the clockDriftTolerance() value (set via
rx2.scheduler.drift-tolerance in minutes) to detect a drift in now(TimeUnit) and
re-adjust the absolute/relative time calculation accordingly.
If the Worker is disposed, the schedule methods
should return the io. singleton instance indicating the disposed
state to the caller. Since the dispose() call can happen on any thread, the schedule implementations
should make best effort to cancel tasks immediately after those tasks have been submitted to the
underlying task-execution scheme if the dispose was detected after this submission.
All methods on the Worker class should be thread safe.
| Modifier and Type | Class and Description |
|---|---|
| pack-priv class | Scheduler.Worker.PeriodicTask
Holds state and logic to calculate when the next delayed invocation of this task has to happen (accounting for clock drifts). |
| Access | Constructor and Description |
|---|---|
| public |
| Modifier and Type | Method and Description |
|---|---|
| public long | |
| public Disposable | |
| public abstract Disposable | Returns: a Disposable to be able to unsubscribe the action (cancel it if not executed)the Runnable to schedule run, long time to "wait" before executing the action; non-positive values indicate an non-delayed
schedule delay, TimeUnit the time unit of unit)delayTimeSchedules an Runnable for execution at some point in the future specified by a time delay relative to the current time. |
| public Disposable | Returns: a Disposable to be able to unsubscribe the action (cancel it if not executed)the Runnable to execute periodically run, final long time to wait before executing the action for the first time; non-positive values indicate
an non-delayed schedule initialDelay, final long the time interval to wait each time in between executing the action; non-positive values
indicate no delay between repeated schedules period, final TimeUnit the time unit of unit)periodSchedules a periodic execution of the given task with the given initial time delay and repeat period. |
| Worker | back to summary |
|---|---|
| public Worker() | |
| now | back to summary |
|---|---|
| public long now(TimeUnit unit) Returns the 'current time' of the Worker in the specified time unit.
| |
| schedule | back to summary |
|---|---|
| public Disposable schedule(Runnable run) Schedules a Runnable for execution without any time delay. The default implementation delegates to
| |
| schedule | back to summary |
|---|---|
| public abstract Disposable schedule(Runnable run, long delay, TimeUnit unit) Schedules an Runnable for execution at some point in the future specified by a time delay relative to the current time.
Note to implementors: non-positive
| |
| schedulePeriodically | back to summary |
|---|---|
| public Disposable schedulePeriodically(Runnable run, final long initialDelay, final long period, final TimeUnit unit) Schedules a periodic execution of the given task with the given initial time delay and repeat period.
The default implementation schedules and reschedules the
Note to implementors: non-positive
| |
| Modifier and Type | Field and Description |
|---|---|
| pack-priv long | |
| pack-priv final Runnable | |
| pack-priv long | |
| pack-priv final long | |
| pack-priv final SequentialDisposable | |
| pack-priv long |
| Access | Constructor and Description |
|---|---|
| pack-priv | PeriodicTask(long firstStartInNanoseconds, Runnable decoratedRun, long firstNowNanoseconds, SequentialDisposable sd, long periodInNanoseconds)
|
| Modifier and Type | Method and Description |
|---|---|
| public Runnable | getWrappedRunnable()
Implements io. |
| public void |
| count | back to summary |
|---|---|
| pack-priv long count | |
| decoratedRun | back to summary |
|---|---|
| pack-priv final Runnable decoratedRun
| |
| lastNowNanoseconds | back to summary |
|---|---|
| pack-priv long lastNowNanoseconds | |
| periodInNanoseconds | back to summary |
|---|---|
| pack-priv final long periodInNanoseconds | |
| sd | back to summary |
|---|---|
| pack-priv final SequentialDisposable sd
| |
| startInNanoseconds | back to summary |
|---|---|
| pack-priv long startInNanoseconds | |
| PeriodicTask | back to summary |
|---|---|
| pack-priv PeriodicTask(long firstStartInNanoseconds, Runnable decoratedRun, long firstNowNanoseconds, SequentialDisposable sd, long periodInNanoseconds) | |
| getWrappedRunnable | back to summary |
|---|---|
| public Runnable getWrappedRunnable() Implements io. Doc from io. Returns the wrapped action. | |
| run | back to summary |
|---|---|
| public void run() Implements java. Doc from java. Runs this operation.
| |