Skip to content

Commit d981bc4

Browse files
author
Andrew Lu
committed
8269428: java/util/concurrent/ConcurrentHashMap/ToArray.java timed out
Reviewed-by: mdoerr Backport-of: 570ad67204a55dd4b45e04e5a91671fed2cc18d0
1 parent 4cee9be commit d981bc4

File tree

1 file changed

+54
-47
lines changed

1 file changed

+54
-47
lines changed
Lines changed: 54 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,8 @@
3131
import java.util.List;
3232
import java.util.concurrent.CompletableFuture;
3333
import java.util.concurrent.ConcurrentHashMap;
34+
import java.util.concurrent.Executors;
35+
import java.util.concurrent.ExecutorService;
3436
import java.util.concurrent.ThreadLocalRandom;
3537
import java.util.stream.Collectors;
3638
import java.util.stream.IntStream;
@@ -45,57 +47,62 @@ public static void main(String[] args) throws Throwable {
4547
}
4648

4749
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;
50+
ExecutorService executor = Executors.newCachedThreadPool();
51+
try {
52+
final ConcurrentHashMap<Integer, Integer> m = new ConcurrentHashMap<>();
53+
final ThreadLocalRandom rnd = ThreadLocalRandom.current();
54+
final int nCPU = Runtime.getRuntime().availableProcessors();
55+
final int minWorkers = 2;
56+
final int maxWorkers = Math.max(minWorkers, Math.min(32, nCPU));
57+
final int nWorkers = rnd.nextInt(minWorkers, maxWorkers + 1);
58+
final int sizePerWorker = 1024;
59+
final int maxSize = nWorkers * sizePerWorker;
5660

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.
61+
// The foreman busy-checks that the size of the arrays obtained
62+
// from the keys and values views grows monotonically until it
63+
// reaches the maximum size.
6064

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;
65+
// NOTE: these size constraints are not specific to toArray and are
66+
// applicable to any form of traversal of the collection views
67+
CompletableFuture<?> foreman = CompletableFuture.runAsync(new Runnable() {
68+
private int prevSize = 0;
6569

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-
}
70+
private boolean checkProgress(Object[] a) {
71+
int size = a.length;
72+
if (size < prevSize || size > maxSize)
73+
throw new AssertionError(
74+
String.format("prevSize=%d size=%d maxSize=%d",
75+
prevSize, size, maxSize));
76+
prevSize = size;
77+
return size == maxSize;
78+
}
7579

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-
});
80+
public void run() {
81+
Integer[] empty = new Integer[0];
82+
for (; ; )
83+
if (checkProgress(m.values().toArray())
84+
& checkProgress(m.keySet().toArray())
85+
& checkProgress(m.values().toArray(empty))
86+
& checkProgress(m.keySet().toArray(empty)))
87+
return;
88+
}
89+
}, executor);
8690

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());
91+
// Each worker puts globally unique keys into the map
92+
List<CompletableFuture<?>> workers =
93+
IntStream.range(0, nWorkers)
94+
.mapToObj(w -> (Runnable) () -> {
95+
for (int i = 0, o = w * sizePerWorker; i < sizePerWorker; i++)
96+
m.put(o + i, i);
97+
})
98+
.map(r -> CompletableFuture.runAsync(r, executor))
99+
.collect(Collectors.toList());
96100

97-
// Wait for workers and foreman to complete
98-
workers.forEach(CompletableFuture<?>::join);
99-
foreman.join();
101+
// Wait for workers and foreman to complete
102+
workers.forEach(CompletableFuture<?>::join);
103+
foreman.join();
104+
} finally {
105+
executor.shutdown();
106+
}
100107
}
101108
}

0 commit comments

Comments
 (0)