|
18 | 18 |
|
19 | 19 | import static com.netflix.hollow.core.util.Threads.daemonThread; |
20 | 20 |
|
21 | | -import java.util.ArrayList; |
22 | | -import java.util.List; |
23 | 21 | import java.util.concurrent.Callable; |
| 22 | +import java.util.concurrent.ConcurrentLinkedQueue; |
24 | 23 | import java.util.concurrent.ExecutionException; |
25 | 24 | import java.util.concurrent.Future; |
26 | 25 | import java.util.concurrent.LinkedBlockingQueue; |
|
30 | 29 | import java.util.concurrent.TimeUnit; |
31 | 30 |
|
32 | 31 | /** |
33 | | - * |
34 | 32 | * A convenience wrapper around ThreadPoolExecutor. Provides sane defaults to |
35 | 33 | * constructor arguments and allows for awaitUninterruptibly(). |
36 | | - * |
| 34 | + * |
| 35 | + * <p><strong>Internal Use:</strong> This class is intended for internal |
| 36 | + * framework use and is not meant for external consumption. |
37 | 37 | */ |
38 | 38 | public class SimultaneousExecutor extends ThreadPoolExecutor { |
39 | 39 |
|
40 | 40 | private static final String DEFAULT_THREAD_NAME = "simultaneous-executor"; |
41 | 41 |
|
42 | | - private final List<Future<?>> futures = new ArrayList<Future<?>>(); |
| 42 | + private final ConcurrentLinkedQueue<Future<?>> futures = new ConcurrentLinkedQueue<>(); |
43 | 43 |
|
44 | 44 | /** |
45 | 45 | * Creates an executor with a thread per processor. |
@@ -253,18 +253,21 @@ public void awaitSuccessfulCompletion() throws InterruptedException, ExecutionEx |
253 | 253 | * if 1 or more tasks failed. |
254 | 254 | * |
255 | 255 | * After this call completes, the thread pool will <i>not</i> be shut down and can be reused. |
| 256 | + * |
| 257 | + * If tasks are being submitted concurrently from other threads while this method executes, |
| 258 | + * the iteration over futures is weakly consistent and may not include all concurrently submitted |
| 259 | + * tasks. Ideally this method should be called after all the tasks are submitted. |
256 | 260 | * |
257 | 261 | * @throws ExecutionException if a computation threw an |
258 | 262 | * exception |
259 | 263 | * @throws InterruptedException if the current thread was interrupted |
260 | 264 | * while waiting |
261 | 265 | */ |
262 | 266 | public void awaitSuccessfulCompletionOfCurrentTasks() throws InterruptedException, ExecutionException { |
263 | | - for(Future<?> f : futures) { |
| 267 | + Future<?> f; |
| 268 | + while ((f = futures.poll()) != null) { |
264 | 269 | f.get(); |
265 | 270 | } |
266 | | - |
267 | | - futures.clear(); |
268 | 271 | } |
269 | 272 |
|
270 | 273 | } |
0 commit comments