Skip to content

Commit 328358a

Browse files
author
David Holmes
committed
8274349: ForkJoinPool.commonPool() does not work with 1 CPU
Backport-of: 2e542e33b81a53652956bb5e9636e7f4af5540f7
1 parent 5e90da9 commit 328358a

File tree

3 files changed

+84
-4
lines changed

3 files changed

+84
-4
lines changed

src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2561,7 +2561,7 @@ private static Object newInstanceFromSystemProperty(String property)
25612561
* overridden by system properties
25622562
*/
25632563
private ForkJoinPool(byte forCommonPoolOnly) {
2564-
int parallelism = Runtime.getRuntime().availableProcessors() - 1;
2564+
int parallelism = Math.max(1, Runtime.getRuntime().availableProcessors() - 1);
25652565
ForkJoinWorkerThreadFactory fac = null;
25662566
UncaughtExceptionHandler handler = null;
25672567
try { // ignore exceptions in accessing/parsing properties
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8274349
27+
* @run main/othervm -XX:ActiveProcessorCount=1 Uniprocessor
28+
* @summary Check the default FJ pool has a reasonable default parallelism
29+
* level in a uniprocessor environment.
30+
*/
31+
32+
import java.util.concurrent.CountDownLatch;
33+
import java.util.concurrent.ForkJoinPool;
34+
35+
public class Uniprocessor {
36+
37+
static volatile boolean done = false;
38+
39+
public static void main(String[] args) throws InterruptedException {
40+
// If the default parallelism were zero then this task would not
41+
// complete and the test will timeout.
42+
CountDownLatch ran = new CountDownLatch(1);
43+
ForkJoinPool.commonPool().submit(() -> ran.countDown());
44+
ran.await();
45+
}
46+
}

test/jdk/java/util/concurrent/tck/ForkJoinPoolTest.java

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import java.util.concurrent.Future;
5252
import java.util.concurrent.RecursiveTask;
5353
import java.util.concurrent.RejectedExecutionException;
54+
import java.util.concurrent.ThreadLocalRandom;
5455
import java.util.concurrent.atomic.AtomicBoolean;
5556
import java.util.concurrent.atomic.AtomicInteger;
5657
import java.util.concurrent.locks.ReentrantLock;
@@ -223,13 +224,46 @@ public void testConstructor2() {
223224
/**
224225
* getParallelism returns size set in constructor
225226
*/
226-
public void testGetParallelism() {
227-
ForkJoinPool p = new ForkJoinPool(1);
227+
public void testGetParallelism_requestedValue() {
228+
int parallelism = ThreadLocalRandom.current().nextInt(1, 4);
229+
ForkJoinPool p = new ForkJoinPool(parallelism);
228230
try (PoolCleaner cleaner = cleaner(p)) {
229-
assertEquals(1, p.getParallelism());
231+
assertEquals(parallelism, p.getParallelism());
230232
}
231233
}
232234

235+
private static int availableProcessors() {
236+
return Runtime.getRuntime().availableProcessors();
237+
}
238+
239+
/**
240+
* default pool parallelism is availableProcessors()
241+
*/
242+
public void testParallelism_defaultValue() {
243+
ForkJoinPool p = new ForkJoinPool();
244+
try (PoolCleaner cleaner = cleaner(p)) {
245+
assertEquals(availableProcessors(), p.getParallelism());
246+
}
247+
}
248+
249+
/**
250+
* default common pool parallelism is max(1, availableProcessors() - 1)
251+
* But getParallelism() returns 1 when property-requested parallelism is 0.
252+
*/
253+
public void testCommonPoolParallelism_defaultValue() {
254+
if (!testImplementationDetails) return;
255+
256+
Integer propertyParallelism =
257+
Integer.getInteger(
258+
"java.util.concurrent.ForkJoinPool.common.parallelism");
259+
260+
int expectedParallelism = (propertyParallelism == null)
261+
? Math.max(1, availableProcessors() - 1)
262+
: Math.max(1, propertyParallelism);
263+
assertEquals(expectedParallelism,
264+
ForkJoinPool.commonPool().getParallelism());
265+
}
266+
233267
/**
234268
* getPoolSize returns number of started workers.
235269
*/

0 commit comments

Comments
 (0)