Skip to content

Commit 3b4f583

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

File tree

1 file changed

+56
-50
lines changed

1 file changed

+56
-50
lines changed
Lines changed: 56 additions & 50 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
@@ -30,6 +30,8 @@
3030

3131
import java.util.concurrent.CompletableFuture;
3232
import java.util.concurrent.ConcurrentHashMap;
33+
import java.util.concurrent.ExecutorService;
34+
import java.util.concurrent.Executors;
3335
import java.util.stream.IntStream;
3436

3537
public class ToArray {
@@ -43,63 +45,67 @@ public static void main(String[] args) throws Throwable {
4345
}
4446

4547
static void executeTest() throws Throwable {
46-
final Throwable[] throwable = new Throwable[1];
47-
final ConcurrentHashMap<Integer, Integer> m = new ConcurrentHashMap<>();
48+
ExecutorService executor = Executors.newCachedThreadPool();
49+
try {
50+
final Throwable[] throwable = new Throwable[1];
51+
final ConcurrentHashMap<Integer, Integer> m = new ConcurrentHashMap<>();
4852

49-
// Number of workers equal to the number of processors
50-
// Each worker will put globally unique keys into the map
51-
final int nWorkers = Runtime.getRuntime().availableProcessors();
52-
final int sizePerWorker = 1024;
53-
final int maxSize = nWorkers * sizePerWorker;
53+
// Number of workers equal to the number of processors
54+
// Each worker will put globally unique keys into the map
55+
final int nWorkers = Runtime.getRuntime().availableProcessors();
56+
final int sizePerWorker = 1024;
57+
final int maxSize = nWorkers * sizePerWorker;
5458

55-
// The foreman keeps checking that the size of the arrays
56-
// obtained from the key and value sets is never less than the
57-
// previously observed size and is never greater than the maximum size
58-
// NOTE: these size constraints are not specific to toArray and are
59-
// applicable to any form of traversal of the collection views
60-
CompletableFuture<?> foreman = CompletableFuture.runAsync(new Runnable() {
61-
private int prevSize = 0;
59+
// The foreman keeps checking that the size of the arrays
60+
// obtained from the key and value sets is never less than the
61+
// previously observed size and is never greater than the maximum size
62+
// NOTE: these size constraints are not specific to toArray and are
63+
// applicable to any form of traversal of the collection views
64+
CompletableFuture<?> foreman = CompletableFuture.runAsync(new Runnable() {
65+
private int prevSize = 0;
6266

63-
private boolean checkProgress(Object[] a) {
64-
int size = a.length;
65-
if (size < prevSize) throw new RuntimeException("WRONG WAY");
66-
if (size > maxSize) throw new RuntimeException("OVERSHOOT");
67-
if (size == maxSize) return true;
68-
prevSize = size;
69-
return false;
70-
}
67+
private boolean checkProgress(Object[] a) {
68+
int size = a.length;
69+
if (size < prevSize) throw new RuntimeException("WRONG WAY");
70+
if (size > maxSize) throw new RuntimeException("OVERSHOOT");
71+
if (size == maxSize) return true;
72+
prevSize = size;
73+
return false;
74+
}
7175

72-
@Override
73-
public void run() {
74-
try {
75-
Integer[] empty = new Integer[0];
76-
while (true) {
77-
if (checkProgress(m.values().toArray())) return;
78-
if (checkProgress(m.keySet().toArray())) return;
79-
if (checkProgress(m.values().toArray(empty))) return;
80-
if (checkProgress(m.keySet().toArray(empty))) return;
76+
@Override
77+
public void run() {
78+
try {
79+
Integer[] empty = new Integer[0];
80+
while (true) {
81+
if (checkProgress(m.values().toArray())) return;
82+
if (checkProgress(m.keySet().toArray())) return;
83+
if (checkProgress(m.values().toArray(empty))) return;
84+
if (checkProgress(m.keySet().toArray(empty))) return;
85+
}
86+
} catch (Throwable t) {
87+
throwable[0] = t;
8188
}
8289
}
83-
catch (Throwable t) {
84-
throwable[0] = t;
85-
}
86-
}
87-
});
90+
}, executor);
8891

89-
// Create workers
90-
// Each worker will put globally unique keys into the map
91-
CompletableFuture<?>[] workers = IntStream.range(0, nWorkers).
92-
mapToObj(w -> CompletableFuture.runAsync(() -> {
93-
for (int i = 0, o = w * sizePerWorker; i < sizePerWorker; i++)
94-
m.put(o + i, i);
95-
})).
96-
toArray(CompletableFuture<?>[]::new);
92+
// Create workers
93+
// Each worker will put globally unique keys into the map
94+
CompletableFuture<?>[] workers = IntStream.range(0, nWorkers).
95+
mapToObj(w -> CompletableFuture.runAsync(() -> {
96+
for (int i = 0, o = w * sizePerWorker; i < sizePerWorker; i++)
97+
m.put(o + i, i);
98+
}, executor)).
99+
toArray(CompletableFuture<?>[]::new);
97100

98-
// Wait for workers and then foreman to complete
99-
CompletableFuture.allOf(workers).join();
100-
foreman.join();
101+
// Wait for workers and then foreman to complete
102+
CompletableFuture.allOf(workers).join();
103+
foreman.join();
101104

102-
if (throwable[0] != null)
103-
throw throwable[0];
105+
if (throwable[0] != null)
106+
throw throwable[0];
107+
} finally {
108+
executor.shutdownNow();
109+
}
104110
}
105111
}

0 commit comments

Comments
 (0)