Skip to content

Commit 8cb3b1f

Browse files
author
Andrew Lu
committed
8269428: java/util/concurrent/ConcurrentHashMap/ToArray.java timed out
Backport-of: 570ad67204a55dd4b45e04e5a91671fed2cc18d0
1 parent 710a0b0 commit 8cb3b1f

File tree

1 file changed

+50
-47
lines changed

1 file changed

+50
-47
lines changed
Lines changed: 50 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
3131
import java.util.List;
3232
import java.util.concurrent.CompletableFuture;
3333
import java.util.concurrent.ConcurrentHashMap;
34+
import java.util.concurrent.Executors;
3435
import java.util.concurrent.ThreadLocalRandom;
3536
import java.util.stream.Collectors;
3637
import java.util.stream.IntStream;
@@ -45,57 +46,59 @@ public static void main(String[] args) throws Throwable {
4546
}
4647

4748
static void executeTest() throws Throwable {
48-
final ConcurrentHashMap<Integer, Integer> m = new ConcurrentHashMap<>();
49-
final ThreadLocalRandom rnd = ThreadLocalRandom.current();
50-
final int nCPU = Runtime.getRuntime().availableProcessors();
51-
final int minWorkers = 2;
52-
final int maxWorkers = Math.max(minWorkers, Math.min(32, nCPU));
53-
final int nWorkers = rnd.nextInt(minWorkers, maxWorkers + 1);
54-
final int sizePerWorker = 1024;
55-
final int maxSize = nWorkers * sizePerWorker;
49+
try (var executor = Executors.newCachedThreadPool()) {
50+
final ConcurrentHashMap<Integer, Integer> m = new ConcurrentHashMap<>();
51+
final ThreadLocalRandom rnd = ThreadLocalRandom.current();
52+
final int nCPU = Runtime.getRuntime().availableProcessors();
53+
final int minWorkers = 2;
54+
final int maxWorkers = Math.max(minWorkers, Math.min(32, nCPU));
55+
final int nWorkers = rnd.nextInt(minWorkers, maxWorkers + 1);
56+
final int sizePerWorker = 1024;
57+
final int maxSize = nWorkers * sizePerWorker;
5658

57-
// The foreman busy-checks that the size of the arrays obtained
58-
// from the keys and values views grows monotonically until it
59-
// reaches the maximum size.
59+
// The foreman busy-checks that the size of the arrays obtained
60+
// from the keys and values views grows monotonically until it
61+
// reaches the maximum size.
6062

61-
// NOTE: these size constraints are not specific to toArray and are
62-
// applicable to any form of traversal of the collection views
63-
CompletableFuture<?> foreman = CompletableFuture.runAsync(new Runnable() {
64-
private int prevSize = 0;
63+
// NOTE: these size constraints are not specific to toArray and are
64+
// applicable to any form of traversal of the collection views
65+
CompletableFuture<?> foreman = CompletableFuture.runAsync(new Runnable() {
66+
private int prevSize = 0;
6567

66-
private boolean checkProgress(Object[] a) {
67-
int size = a.length;
68-
if (size < prevSize || size > maxSize)
69-
throw new AssertionError(
70-
String.format("prevSize=%d size=%d maxSize=%d",
71-
prevSize, size, maxSize));
72-
prevSize = size;
73-
return size == maxSize;
74-
}
68+
private boolean checkProgress(Object[] a) {
69+
int size = a.length;
70+
if (size < prevSize || size > maxSize)
71+
throw new AssertionError(
72+
String.format("prevSize=%d size=%d maxSize=%d",
73+
prevSize, size, maxSize));
74+
prevSize = size;
75+
return size == maxSize;
76+
}
7577

76-
public void run() {
77-
Integer[] empty = new Integer[0];
78-
for (;;)
79-
if (checkProgress(m.values().toArray())
80-
& checkProgress(m.keySet().toArray())
81-
& checkProgress(m.values().toArray(empty))
82-
& checkProgress(m.keySet().toArray(empty)))
83-
return;
84-
}
85-
});
78+
public void run() {
79+
Integer[] empty = new Integer[0];
80+
for (; ; )
81+
if (checkProgress(m.values().toArray())
82+
& checkProgress(m.keySet().toArray())
83+
& checkProgress(m.values().toArray(empty))
84+
& checkProgress(m.keySet().toArray(empty)))
85+
return;
86+
}
87+
}, executor);
8688

87-
// Each worker puts globally unique keys into the map
88-
List<CompletableFuture<?>> workers =
89-
IntStream.range(0, nWorkers)
90-
.mapToObj(w -> (Runnable) () -> {
91-
for (int i = 0, o = w * sizePerWorker; i < sizePerWorker; i++)
92-
m.put(o + i, i);
93-
})
94-
.map(CompletableFuture::runAsync)
95-
.collect(Collectors.toList());
89+
// Each worker puts globally unique keys into the map
90+
List<CompletableFuture<?>> workers =
91+
IntStream.range(0, nWorkers)
92+
.mapToObj(w -> (Runnable) () -> {
93+
for (int i = 0, o = w * sizePerWorker; i < sizePerWorker; i++)
94+
m.put(o + i, i);
95+
})
96+
.map(r -> CompletableFuture.runAsync(r, executor))
97+
.collect(Collectors.toList());
9698

97-
// Wait for workers and foreman to complete
98-
workers.forEach(CompletableFuture<?>::join);
99-
foreman.join();
99+
// Wait for workers and foreman to complete
100+
workers.forEach(CompletableFuture<?>::join);
101+
foreman.join();
102+
}
100103
}
101104
}

0 commit comments

Comments
 (0)