Skip to content

Commit 3e17f59

Browse files
committed
fix lang-1817
restore interruption status of the thread
1 parent 7bcb03a commit 3e17f59

2 files changed

Lines changed: 47 additions & 7 deletions

File tree

src/main/java/org/apache/commons/lang3/concurrent/UncheckedFutureImpl.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public V get() {
4242
try {
4343
return super.get();
4444
} catch (final InterruptedException e) {
45+
Thread.currentThread().interrupt();
4546
throw new UncheckedInterruptedException(e);
4647
} catch (final ExecutionException e) {
4748
throw new UncheckedExecutionException(e);
@@ -53,6 +54,7 @@ public V get(final long timeout, final TimeUnit unit) {
5354
try {
5455
return super.get(timeout, unit);
5556
} catch (final InterruptedException e) {
57+
Thread.currentThread().interrupt();
5658
throw new UncheckedInterruptedException(e);
5759
} catch (final ExecutionException e) {
5860
throw new UncheckedExecutionException(e);

src/test/java/org/apache/commons/lang3/concurrent/UncheckedFutureTest.java

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,19 @@
1717

1818
package org.apache.commons.lang3.concurrent;
1919

20-
import static org.junit.jupiter.api.Assertions.assertEquals;
21-
import static org.junit.jupiter.api.Assertions.assertThrows;
22-
2320
import java.util.Arrays;
2421
import java.util.List;
25-
import java.util.concurrent.ExecutionException;
26-
import java.util.concurrent.Future;
27-
import java.util.concurrent.TimeUnit;
28-
import java.util.concurrent.TimeoutException;
22+
import java.util.concurrent.*;
23+
import java.util.function.Consumer;
2924
import java.util.stream.Collectors;
3025

3126
import org.apache.commons.lang3.AbstractLangTest;
3227
import org.apache.commons.lang3.exception.UncheckedInterruptedException;
28+
import org.junit.jupiter.api.RepeatedTest;
3329
import org.junit.jupiter.api.Test;
3430

31+
import static org.junit.jupiter.api.Assertions.*;
32+
3533
/**
3634
* Tests {@link UncheckedFuture}.
3735
*/
@@ -121,4 +119,44 @@ void testOnFuture() {
121119
assertEquals("Z", UncheckedFuture.on(new TestFuture<>("Z")).get());
122120
}
123121

122+
@RepeatedTest(10)
123+
void interruptFlagIsPreservedOnGet() throws Exception {
124+
assertInterruptPreserved(future -> future.get());
125+
}
126+
127+
@RepeatedTest(10)
128+
void interruptFlagIsPreservedOnGetWithTimeout() throws Exception {
129+
assertInterruptPreserved(future -> future.get(2, TimeUnit.SECONDS));
130+
}
131+
132+
private static void assertInterruptPreserved(
133+
Consumer<UncheckedFuture<Integer>> futureCall) throws Exception {
134+
135+
ExecutorService executor = Executors.newFixedThreadPool(2);
136+
try {
137+
CountDownLatch future2IsAboutToWait = new CountDownLatch(1);
138+
Future<Integer> future1 = executor.submit(() -> {
139+
Thread.sleep(10_000);
140+
return 42;
141+
});
142+
Future<Integer> future2 = executor.submit(() -> {
143+
future2IsAboutToWait.countDown();
144+
try {
145+
futureCall.accept(UncheckedFuture.on(future1));
146+
return 1;
147+
} catch (RuntimeException e) {
148+
assertTrue(Thread.currentThread().isInterrupted());
149+
return 2;
150+
}
151+
});
152+
153+
assertTrue(future2IsAboutToWait.await(2, TimeUnit.SECONDS));
154+
executor.shutdownNow();
155+
assertEquals(2, future2.get(2, TimeUnit.SECONDS));
156+
} finally {
157+
executor.shutdownNow();
158+
executor.awaitTermination(10, TimeUnit.SECONDS);
159+
}
160+
}
161+
124162
}

0 commit comments

Comments
 (0)