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 ;
35
+ import java .util .concurrent .ExecutorService ;
34
36
import java .util .concurrent .ThreadLocalRandom ;
35
37
import java .util .stream .Collectors ;
36
38
import java .util .stream .IntStream ;
@@ -45,57 +47,62 @@ public static void main(String[] args) throws Throwable {
45
47
}
46
48
47
49
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 ;
56
60
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.
60
64
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 ;
65
69
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
+ }
75
79
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 );
86
90
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 ());
96
100
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
+ }
100
107
}
101
108
}
0 commit comments