16
16
package rx .schedulers ;
17
17
18
18
import rx .Scheduler ;
19
- import rx .internal .schedulers .*;
19
+ import rx .annotations .Experimental ;
20
+ import rx .internal .schedulers .ExecutorScheduler ;
21
+ import rx .internal .schedulers .GenericScheduledExecutorService ;
22
+ import rx .internal .schedulers .SchedulerLifecycle ;
20
23
import rx .internal .util .RxRingBuffer ;
21
24
import rx .plugins .RxJavaPlugins ;
22
25
import rx .plugins .RxJavaSchedulersHook ;
23
26
24
27
import java .util .concurrent .Executor ;
28
+ import java .util .concurrent .atomic .AtomicReference ;
25
29
26
30
/**
27
31
* Static factory methods for creating Schedulers.
@@ -32,7 +36,22 @@ public final class Schedulers {
32
36
private final Scheduler ioScheduler ;
33
37
private final Scheduler newThreadScheduler ;
34
38
35
- private static final Schedulers INSTANCE = new Schedulers ();
39
+ private static final AtomicReference <Schedulers > INSTANCE = new AtomicReference <Schedulers >();
40
+
41
+ private static Schedulers getInstance () {
42
+ for (;;) {
43
+ Schedulers current = INSTANCE .get ();
44
+ if (current != null ) {
45
+ return current ;
46
+ }
47
+ current = new Schedulers ();
48
+ if (INSTANCE .compareAndSet (null , current )) {
49
+ return current ;
50
+ } else {
51
+ shutdown ();
52
+ }
53
+ }
54
+ }
36
55
37
56
private Schedulers () {
38
57
RxJavaSchedulersHook hook = RxJavaPlugins .getInstance ().getSchedulersHook ();
@@ -86,7 +105,7 @@ public static Scheduler trampoline() {
86
105
* @return a {@link Scheduler} that creates new threads
87
106
*/
88
107
public static Scheduler newThread () {
89
- return INSTANCE .newThreadScheduler ;
108
+ return getInstance () .newThreadScheduler ;
90
109
}
91
110
92
111
/**
@@ -101,7 +120,7 @@ public static Scheduler newThread() {
101
120
* @return a {@link Scheduler} meant for computation-bound work
102
121
*/
103
122
public static Scheduler computation () {
104
- return INSTANCE .computationScheduler ;
123
+ return getInstance () .computationScheduler ;
105
124
}
106
125
107
126
/**
@@ -118,7 +137,7 @@ public static Scheduler computation() {
118
137
* @return a {@link Scheduler} meant for IO-bound work
119
138
*/
120
139
public static Scheduler io () {
121
- return INSTANCE .ioScheduler ;
140
+ return getInstance () .ioScheduler ;
122
141
}
123
142
124
143
/**
@@ -141,13 +160,27 @@ public static TestScheduler test() {
141
160
public static Scheduler from (Executor executor ) {
142
161
return new ExecutorScheduler (executor );
143
162
}
163
+
164
+ /**
165
+ * Resets the current {@link Schedulers} instance.
166
+ * <p>
167
+ * This API is experimental. Resetting the schedulers is dangerous
168
+ * during application runtime and also bad code could invoke it in
169
+ * the middle of an application life-cycle and really break applications
170
+ * if not used cautiously.
171
+ */
172
+ @ Experimental
173
+ public static void reset () {
174
+ shutdown ();
175
+ INSTANCE .set (null );
176
+ }
144
177
145
178
/**
146
179
* Starts those standard Schedulers which support the SchedulerLifecycle interface.
147
180
* <p>The operation is idempotent and threadsafe.
148
181
*/
149
182
/* public test only */ static void start () {
150
- Schedulers s = INSTANCE ;
183
+ Schedulers s = getInstance () ;
151
184
synchronized (s ) {
152
185
if (s .computationScheduler instanceof SchedulerLifecycle ) {
153
186
((SchedulerLifecycle ) s .computationScheduler ).start ();
@@ -170,7 +203,7 @@ public static Scheduler from(Executor executor) {
170
203
* <p>The operation is idempotent and threadsafe.
171
204
*/
172
205
public static void shutdown () {
173
- Schedulers s = INSTANCE ;
206
+ Schedulers s = getInstance () ;
174
207
synchronized (s ) {
175
208
if (s .computationScheduler instanceof SchedulerLifecycle ) {
176
209
((SchedulerLifecycle ) s .computationScheduler ).shutdown ();
@@ -181,12 +214,12 @@ public static void shutdown() {
181
214
if (s .newThreadScheduler instanceof SchedulerLifecycle ) {
182
215
((SchedulerLifecycle ) s .newThreadScheduler ).shutdown ();
183
216
}
184
-
217
+
185
218
GenericScheduledExecutorService .INSTANCE .shutdown ();
186
-
219
+
187
220
RxRingBuffer .SPSC_POOL .shutdown ();
188
-
221
+
189
222
RxRingBuffer .SPMC_POOL .shutdown ();
190
223
}
191
224
}
192
- }
225
+ }
0 commit comments