11
11
import java .util .concurrent .SynchronousQueue ;
12
12
import java .util .concurrent .ThreadPoolExecutor ;
13
13
import java .util .concurrent .TimeUnit ;
14
+ import java .util .concurrent .atomic .AtomicBoolean ;
14
15
import java .util .function .Function ;
15
16
import java .util .function .Supplier ;
16
17
@@ -31,7 +32,8 @@ final class Dispatcher<T> {
31
32
private final Executor executor ;
32
33
private final Semaphore limiter ;
33
34
34
- private volatile boolean started = false ;
35
+ private final AtomicBoolean started = new AtomicBoolean (false );
36
+
35
37
private volatile boolean shortCircuited = false ;
36
38
37
39
private Dispatcher (Executor executor , int permits ) {
@@ -44,22 +46,23 @@ static <T> Dispatcher<T> of(Executor executor, int permits) {
44
46
}
45
47
46
48
void start () {
47
- started = true ;
48
- dispatcher .execute (() -> {
49
- try {
50
- while (true ) {
51
- Runnable task ;
52
- if ((task = workingQueue .take ()) != POISON_PILL ) {
53
- limiter .acquire ();
54
- executor .execute (withFinally (task , limiter ::release ));
55
- } else {
56
- break ;
49
+ if (!started .getAndSet (true )) {
50
+ dispatcher .execute (() -> {
51
+ try {
52
+ while (true ) {
53
+ Runnable task ;
54
+ if ((task = workingQueue .take ()) != POISON_PILL ) {
55
+ limiter .acquire ();
56
+ executor .execute (withFinally (task , limiter ::release ));
57
+ } else {
58
+ break ;
59
+ }
57
60
}
61
+ } catch (Throwable e ) {
62
+ handle (e );
58
63
}
59
- } catch (Throwable e ) {
60
- handle (e );
61
- }
62
- });
64
+ });
65
+ }
63
66
}
64
67
65
68
void stop () {
@@ -73,7 +76,7 @@ void stop() {
73
76
}
74
77
75
78
boolean isRunning () {
76
- return started ;
79
+ return started . get () ;
77
80
}
78
81
79
82
CompletableFuture <T > enqueue (Supplier <T > supplier ) {
0 commit comments