1515import java .util .List ;
1616import java .util .Queue ;
1717import java .util .concurrent .CompletableFuture ;
18+ import java .util .concurrent .ExecutorService ;
19+ import java .util .concurrent .Executors ;
1820import java .util .concurrent .TimeUnit ;
1921import java .util .concurrent .atomic .AtomicBoolean ;
2022import java .util .function .Function ;
2426import static org .assertj .core .api .Assertions .assertThat ;
2527
2628class QueueServiceTest {
29+
30+ private ExecutorService executorService ;
31+
2732 @ InjectMocks
2833 @ Spy
2934 private QueueService queueService ;
3035
3136 @ BeforeEach
3237 void setUp () {
38+ executorService = Executors .newSingleThreadExecutor ();
3339 MockitoAnnotations .openMocks (this );
3440 }
3541
@@ -75,12 +81,15 @@ void shouldRunHighPriorityRunnable() {
7581
7682 // Start execution thread.
7783 // It won't stop itself, so we have to do it.
78- final CompletableFuture < Void > tasksExecutionFuture = CompletableFuture .runAsync (queueService ::executeActions );
84+ CompletableFuture .runAsync (queueService ::executeActions , executorService );
7985 Awaitility
8086 .await ()
8187 .atMost (5 , TimeUnit .SECONDS )
8288 .until (() -> highPriorityTimestamps .size () == 1 );
83- tasksExecutionFuture .cancel (true );
89+ // Thread blocks indefinitely on PriorityBlockingQueue#take and needs to be interrupted
90+ // CompletableFuture#cancel does not interrupt the thread, an ExecutorService is needed
91+ // A call to ExecutorService#shutdownNow is done to interrupt the thread
92+ executorService .shutdownNow ();
8493
8594 // We simply ensure the execution has completed.
8695 assertThat (highPriorityTimestamps .size ()).isOne ();
@@ -95,12 +104,15 @@ void shouldRunLowPriorityRunnable() {
95104
96105 // Start execution thread.
97106 // It won't stop itself, so we have to do it.
98- final CompletableFuture < Void > tasksExecutionFuture = CompletableFuture .runAsync (queueService ::executeActions );
107+ CompletableFuture .runAsync (queueService ::executeActions , executorService );
99108 Awaitility
100109 .await ()
101110 .atMost (5 , TimeUnit .SECONDS )
102111 .until (() -> lowPriorityTimestamps .size () == 1 );
103- tasksExecutionFuture .cancel (true );
112+ // Thread blocks indefinitely on PriorityBlockingQueue#take and needs to be interrupted
113+ // CompletableFuture#cancel does not interrupt the thread, an ExecutorService is needed
114+ // A call to ExecutorService#shutdownNow is done to interrupt the thread
115+ executorService .shutdownNow ();
104116
105117 // We simply ensure the execution has completed.
106118 assertThat (lowPriorityTimestamps .size ()).isOne ();
@@ -121,12 +133,15 @@ void shouldRunHighPriorityBeforeLowPriority() {
121133
122134 // Start execution thread.
123135 // It won't stop itself, so we have to do it.
124- final CompletableFuture < Void > tasksExecutionFuture = CompletableFuture .runAsync (queueService ::executeActions );
136+ CompletableFuture .runAsync (queueService ::executeActions );
125137 Awaitility
126138 .await ()
127139 .atMost (5 , TimeUnit .SECONDS )
128140 .until (() -> highPriorityTimestamps .size () == 1 && lowPriorityTimestamps .size () == 1 );
129- tasksExecutionFuture .cancel (true );
141+ // Thread blocks indefinitely on PriorityBlockingQueue#take and needs to be interrupted
142+ // CompletableFuture#cancel does not interrupt the thread, an ExecutorService is needed
143+ // A call to ExecutorService#shutdownNow is done to interrupt the thread
144+ executorService .shutdownNow ();
130145
131146 // We have executed a single task per priority so we that's what we should now have.
132147 assertThat (highPriorityTimestamps .size ()).isOne ();
@@ -177,12 +192,15 @@ void shouldExecuteInOrder() throws NoSuchFieldException {
177192
178193 // Start execution thread.
179194 // It won't stop itself, so we have to do it.
180- final CompletableFuture < Void > executionFuture = CompletableFuture .runAsync (queueService ::executeActions );
195+ CompletableFuture .runAsync (queueService ::executeActions , executorService );
181196 Awaitility
182197 .await ()
183198 .atMost (5 , TimeUnit .SECONDS )
184199 .until (() -> executionOrder .size () == totalTasksNumber );
185- executionFuture .cancel (true );
200+ // Thread blocks indefinitely on PriorityBlockingQueue#take and needs to be interrupted
201+ // CompletableFuture#cancel does not interrupt the thread, an ExecutorService is needed
202+ // A call to ExecutorService#shutdownNow is done to interrupt the thread
203+ executorService .shutdownNow ();
186204
187205 // Tasks should have been executed in the right order.
188206 // This should look like [0, 1, 2, 3, 4, 5].
0 commit comments