|
1 | 1 | /* |
2 | | - * Copyright 2019 Björn Kautler |
| 2 | + * Copyright 2020 Björn Kautler |
3 | 3 | * |
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | 5 | * you may not use this file except in compliance with the License. |
|
22 | 22 | import net.kautler.command.api.prefix.PrefixProvider; |
23 | 23 | import net.kautler.command.api.restriction.Restriction; |
24 | 24 | import net.kautler.command.restriction.RestrictionLookup; |
| 25 | +import net.kautler.command.util.lazy.LazyReferenceBySupplier; |
25 | 26 | import org.apache.logging.log4j.Logger; |
26 | 27 |
|
27 | 28 | import javax.annotation.PostConstruct; |
|
38 | 39 | import java.util.Map; |
39 | 40 | import java.util.concurrent.ConcurrentHashMap; |
40 | 41 | import java.util.concurrent.ExecutorService; |
41 | | -import java.util.concurrent.locks.Lock; |
42 | | -import java.util.concurrent.locks.ReadWriteLock; |
43 | | -import java.util.concurrent.locks.ReentrantReadWriteLock; |
| 42 | +import java.util.concurrent.Executors; |
44 | 43 | import java.util.regex.Matcher; |
45 | 44 | import java.util.regex.Pattern; |
46 | 45 |
|
47 | 46 | import static java.lang.String.format; |
48 | 47 | import static java.util.concurrent.CompletableFuture.runAsync; |
49 | | -import static java.util.concurrent.Executors.newCachedThreadPool; |
50 | 48 | import static java.util.stream.Collectors.joining; |
51 | 49 | import static java.util.stream.Collectors.toList; |
52 | 50 | import static java.util.stream.Collectors.toMap; |
@@ -118,29 +116,11 @@ public abstract class CommandHandler<M> { |
118 | 116 | */ |
119 | 117 | private final RestrictionLookup<M> availableRestrictions = new RestrictionLookup<>(); |
120 | 118 |
|
121 | | - /** |
122 | | - * A read lock for lazy initialization of the executor service. |
123 | | - */ |
124 | | - private final Lock readLock; |
125 | | - |
126 | | - /** |
127 | | - * A write lock for lazy initialization of the executor service. |
128 | | - */ |
129 | | - private final Lock writeLock; |
130 | | - |
131 | 119 | /** |
132 | 120 | * An executor service for asynchronous command execution. |
133 | 121 | */ |
134 | | - private ExecutorService executorService; |
135 | | - |
136 | | - /** |
137 | | - * Constructs a new command handler. |
138 | | - */ |
139 | | - public CommandHandler() { |
140 | | - ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); |
141 | | - readLock = readWriteLock.readLock(); |
142 | | - writeLock = readWriteLock.writeLock(); |
143 | | - } |
| 122 | + private final LazyReferenceBySupplier<ExecutorService> executorService = |
| 123 | + new LazyReferenceBySupplier<>(Executors::newCachedThreadPool); |
144 | 124 |
|
145 | 125 | /** |
146 | 126 | * Ensures the implementing command handlers are initialized on startup. |
@@ -295,8 +275,8 @@ private void determineProcessors() { |
295 | 275 | */ |
296 | 276 | @PreDestroy |
297 | 277 | private void shutdownExecutorService() { |
298 | | - if (executorService != null) { |
299 | | - executorService.shutdown(); |
| 278 | + if (executorService.isSet()) { |
| 279 | + executorService.get().shutdown(); |
300 | 280 | } |
301 | 281 | } |
302 | 282 |
|
@@ -434,40 +414,11 @@ private boolean isCommandAllowed(M message, Command<? super M> command) { |
434 | 414 | * @param commandExecutor the executor that runs the actual command implementation |
435 | 415 | */ |
436 | 416 | protected void executeAsync(M message, Runnable commandExecutor) { |
437 | | - runAsync(commandExecutor, getExecutorService()) |
| 417 | + runAsync(commandExecutor, executorService.get()) |
438 | 418 | .whenComplete((nothing, throwable) -> { |
439 | 419 | if (throwable != null) { |
440 | 420 | logger.error("Exception while executing command asynchronously", throwable); |
441 | 421 | } |
442 | 422 | }); |
443 | 423 | } |
444 | | - |
445 | | - /** |
446 | | - * Returns the executor service that is used for asynchronous command execution. |
447 | | - * |
448 | | - * @return the executor service that is used for asynchronous command execution |
449 | | - */ |
450 | | - private ExecutorService getExecutorService() { |
451 | | - readLock.lock(); |
452 | | - try { |
453 | | - if (executorService == null) { |
454 | | - readLock.unlock(); |
455 | | - try { |
456 | | - writeLock.lock(); |
457 | | - try { |
458 | | - if (executorService == null) { |
459 | | - executorService = newCachedThreadPool(); |
460 | | - } |
461 | | - } finally { |
462 | | - writeLock.unlock(); |
463 | | - } |
464 | | - } finally { |
465 | | - readLock.lock(); |
466 | | - } |
467 | | - } |
468 | | - return executorService; |
469 | | - } finally { |
470 | | - readLock.unlock(); |
471 | | - } |
472 | | - } |
473 | 424 | } |
0 commit comments