Skip to content

Commit 6f67abd

Browse files
viktorklang-oraAlan Bateman
authored andcommitted
8304557: java/util/concurrent/CompletableFuture/CompletableFutureOrTimeoutExceptionallyTest.java times out
Reviewed-by: jpai
1 parent 568dd57 commit 6f67abd

File tree

1 file changed

+34
-14
lines changed

1 file changed

+34
-14
lines changed

test/jdk/java/util/concurrent/CompletableFuture/CompletableFutureOrTimeoutExceptionallyTest.java

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,39 +25,59 @@
2525
* @test
2626
* @bug 8303742
2727
* @summary CompletableFuture.orTimeout can leak memory if completed exceptionally
28+
* @modules java.base/java.util.concurrent:open
2829
* @run junit/othervm -Xmx128m CompletableFutureOrTimeoutExceptionallyTest
2930
*/
3031

3132
import java.time.Duration;
33+
import java.util.concurrent.BlockingQueue;
3234
import java.util.concurrent.CompletableFuture;
35+
import java.util.concurrent.ScheduledThreadPoolExecutor;
3336
import java.util.concurrent.TimeUnit;
3437

3538
import org.junit.jupiter.api.Test;
39+
import static org.junit.jupiter.api.Assertions.assertTrue;
3640

3741
class CompletableFutureOrTimeoutExceptionallyTest {
42+
static final BlockingQueue<Runnable> delayerQueue;
43+
static {
44+
try {
45+
var delayerClass = Class.forName("java.util.concurrent.CompletableFuture$Delayer",
46+
true,
47+
CompletableFuture.class.getClassLoader());
48+
var delayerField = delayerClass.getDeclaredField("delayer");
49+
delayerField.setAccessible(true);
50+
delayerQueue = ((ScheduledThreadPoolExecutor)delayerField.get(null)).getQueue();
51+
} catch (Throwable t) {
52+
throw new ExceptionInInitializerError(t);
53+
}
54+
}
55+
3856
/**
3957
* Test that orTimeout task is cancelled if the CompletableFuture is completed Exceptionally
4058
*/
4159
@Test
42-
void testOrTimeoutWithCompleteExceptionallyDoesNotLeak() {
43-
var count = 0L;
44-
while (count++ < 2_000_000) {
45-
new CompletableFuture<>()
46-
.orTimeout(12, TimeUnit.HOURS)
47-
.completeExceptionally(new RuntimeException("This is fine"));
48-
}
60+
void testOrTimeoutWithCompleteExceptionallyDoesNotLeak() throws InterruptedException {
61+
assertTrue(delayerQueue.peek() == null);
62+
var future = new CompletableFuture<>().orTimeout(12, TimeUnit.HOURS);
63+
assertTrue(delayerQueue.peek() != null);
64+
future.completeExceptionally(new RuntimeException("This is fine"));
65+
while (delayerQueue.peek() != null) {
66+
Thread.sleep(100);
67+
};
4968
}
5069

5170
/**
5271
* Test that the completeOnTimeout task is cancelled if the CompletableFuture is completed Exceptionally
5372
*/
5473
@Test
55-
void testCompleteOnTimeoutWithCompleteExceptionallyDoesNotLeak() {
56-
var count = 0L;
57-
while (count++ < 2_000_000) {
58-
new CompletableFuture<>()
59-
.completeOnTimeout(null, 12, TimeUnit.HOURS)
60-
.completeExceptionally(new RuntimeException("This is fine"));
61-
}
74+
void testCompleteOnTimeoutWithCompleteExceptionallyDoesNotLeak() throws InterruptedException {
75+
assertTrue(delayerQueue.peek() == null);
76+
var future = new CompletableFuture<>().completeOnTimeout(null, 12, TimeUnit.HOURS);
77+
assertTrue(delayerQueue.peek() != null);
78+
future.completeExceptionally(new RuntimeException("This is fine"));
79+
while (delayerQueue.peek() != null) {
80+
Thread.sleep(100);
81+
};
6282
}
6383
}

0 commit comments

Comments
 (0)