1
1
/*
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.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
31
31
import java .util .List ;
32
32
import java .util .concurrent .CompletableFuture ;
33
33
import java .util .concurrent .ConcurrentHashMap ;
34
+ import java .util .concurrent .Executors ;
34
35
import java .util .concurrent .ThreadLocalRandom ;
35
36
import java .util .stream .Collectors ;
36
37
import java .util .stream .IntStream ;
@@ -45,57 +46,59 @@ public static void main(String[] args) throws Throwable {
45
46
}
46
47
47
48
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 ;
56
58
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.
60
62
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 ;
65
67
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
+ }
75
77
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 );
86
88
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 ());
96
98
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
+ }
100
103
}
101
104
}
0 commit comments