1
1
/*
2
- * Copyright (c) 2003, 2015 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2003, 2020 , 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
32
32
*/
33
33
34
34
import java .lang .management .*;
35
- import java .time .Instant ;
35
+ import java .text .MessageFormat ;
36
+ import java .util .Arrays ;
37
+ import java .util .HashSet ;
38
+ import java .util .Set ;
36
39
import java .util .concurrent .Phaser ;
37
40
import java .util .function .Supplier ;
38
41
@@ -61,12 +64,14 @@ public String toString() {
61
64
static final int ALL_THREADS = DAEMON_THREADS + USER_THREADS ;
62
65
private static final boolean live [] = new boolean [ALL_THREADS ];
63
66
private static final Thread allThreads [] = new Thread [ALL_THREADS ];
67
+ private static final Set <Long > allThreadIds = new HashSet <>();
68
+
64
69
private static final ThreadMXBean mbean = ManagementFactory .getThreadMXBean ();
65
70
private static boolean testFailed = false ;
66
71
private static boolean trace = false ;
67
72
68
73
private static long prevTotalThreadCount = 0 ;
69
- private static int prevLiveThreadCount = 0 ;
74
+ private static long prevLiveTestThreadCount = 0 ;
70
75
private static int prevPeakThreadCount = 0 ;
71
76
72
77
private static final Phaser startupCheck = new Phaser (ALL_THREADS + 1 );
@@ -95,9 +100,11 @@ private static void checkAllThreadsAlive() throws Exception {
95
100
// Start all threads and wait to be sure they all are alive
96
101
for (int i = 0 ; i < ALL_THREADS ; i ++) {
97
102
setLive (i , true );
98
- allThreads [i ] = new MyThread (i );
99
- allThreads [i ].setDaemon (i < DAEMON_THREADS );
100
- allThreads [i ].start ();
103
+ Thread thread = new MyThread (i );
104
+ thread .setDaemon (i < DAEMON_THREADS );
105
+ thread .start ();
106
+ allThreadIds .add (thread .getId ());
107
+ allThreads [i ] = thread ;
101
108
}
102
109
// wait until all threads are started.
103
110
startupCheck .arriveAndAwaitAdvance ();
@@ -107,30 +114,13 @@ private static void checkAllThreadsAlive() throws Exception {
107
114
printThreadList ();
108
115
}
109
116
// Check mbean now. All threads must appear in getAllThreadIds() list
110
- long [] list = mbean .getAllThreadIds ();
111
-
112
- for (int i = 0 ; i < ALL_THREADS ; i ++) {
113
- long expectedId = allThreads [i ].getId ();
114
- boolean found = false ;
117
+ Set <Long > currentThreadIds = new HashSet <>();
118
+ Arrays .stream (mbean .getAllThreadIds ()).forEach (currentThreadIds ::add );
115
119
120
+ if (!currentThreadIds .containsAll (allThreadIds )) {
121
+ testFailed = true ;
116
122
if (trace ) {
117
- System .out .print ("Looking for thread with id " + expectedId );
118
- }
119
- for (int j = 0 ; j < list .length ; j ++) {
120
- if (expectedId == list [j ]) {
121
- found = true ;
122
- break ;
123
- }
124
- }
125
-
126
- if (!found ) {
127
- testFailed = true ;
128
- }
129
- if (trace ) {
130
- if (!found ) {
131
- System .out .print (". TEST FAILED." );
132
- }
133
- System .out .println ();
123
+ System .out .print (". TEST FAILED." );
134
124
}
135
125
}
136
126
if (trace ) {
@@ -201,112 +191,65 @@ private static void checkAllThreadsDead() throws Exception {
201
191
}
202
192
203
193
private static void checkThreadCount (int numNewThreads ,
204
- int numTerminatedThreads )
205
- throws Exception {
206
-
194
+ int numTerminatedThreads ) {
207
195
checkLiveThreads (numNewThreads , numTerminatedThreads );
208
196
checkPeakThreads (numNewThreads );
209
197
checkTotalThreads (numNewThreads );
210
- checkThreadIds ();
198
+ checkThreadIds (numNewThreads , numTerminatedThreads );
211
199
}
212
200
213
201
private static void checkLiveThreads (int numNewThreads ,
214
- int numTerminatedThreads )
215
- throws InterruptedException {
202
+ int numTerminatedThreads ) {
216
203
int diff = numNewThreads - numTerminatedThreads ;
217
-
218
- waitTillEquals (
219
- diff + prevLiveThreadCount ,
220
- ()->(long )mbean .getThreadCount (),
221
- "Unexpected number of live threads: " +
222
- " Prev live = %1$d Current live = ${provided} Threads added = %2$d" +
223
- " Threads terminated = %3$d" ,
224
- ()->prevLiveThreadCount ,
225
- ()->numNewThreads ,
226
- ()->numTerminatedThreads
227
- );
204
+ long threadCount = mbean .getThreadCount ();
205
+ long expectedThreadCount = prevLiveTestThreadCount + diff ;
206
+ // Check that number of live test threads is no less
207
+ // than number of all threads returned by mbean.getThreadCount()
208
+ if (threadCount < expectedThreadCount ) {
209
+ testFailed = true ;
210
+ System .err .println (MessageFormat .format ("Unexpected number of threads count %d." +
211
+ "The expected number is %d or greater" , threadCount , expectedThreadCount ));
212
+ }
228
213
}
229
214
230
- private static void checkPeakThreads (int numNewThreads )
231
- throws InterruptedException {
232
-
233
- waitTillEquals (numNewThreads + prevPeakThreadCount ,
234
- ()->(long )mbean .getPeakThreadCount (),
235
- "Unexpected number of peak threads: " +
236
- " Prev peak = %1$d Current peak = ${provided} Threads added = %2$d" ,
237
- ()->prevPeakThreadCount ,
238
- ()->numNewThreads
239
- );
215
+ private static void checkPeakThreads (int numNewThreads ) {
216
+ long peakThreadCount = mbean .getPeakThreadCount ();
217
+ long expectedThreadCount = Math .max (prevPeakThreadCount , numNewThreads );
218
+ if (peakThreadCount < expectedThreadCount ) {
219
+ testFailed = true ;
220
+ System .err .println (MessageFormat .format ("Unexpected number of peak threads count %d." +
221
+ "The expected number is %d or greater" , peakThreadCount , expectedThreadCount ));
222
+ }
240
223
}
241
224
242
- private static void checkTotalThreads (int numNewThreads )
243
- throws InterruptedException {
244
-
245
- waitTillEquals (numNewThreads + prevTotalThreadCount ,
246
- ()->mbean .getTotalStartedThreadCount (),
247
- "Unexpected number of total threads: " +
248
- " Prev Total = %1$d Current Total = ${provided} Threads added = %2$d" ,
249
- ()->prevTotalThreadCount ,
250
- ()->numNewThreads
251
- );
225
+ private static void checkTotalThreads (int numNewThreads ) {
226
+ long totalThreadCount = mbean .getTotalStartedThreadCount ();
227
+ long expectedThreadCount = prevTotalThreadCount + numNewThreads ;
228
+ if (totalThreadCount < expectedThreadCount ) {
229
+ testFailed = true ;
230
+ System .err .println (MessageFormat .format ("Unexpected number of total threads %d." +
231
+ "The expected number is %d or greater" , totalThreadCount , expectedThreadCount ));
232
+ }
252
233
}
253
234
254
- private static void checkThreadIds () throws InterruptedException {
255
- long [] list = mbean .getAllThreadIds ();
256
-
257
- waitTillEquals (
258
- list .length ,
259
- ()->(long )mbean .getThreadCount (),
260
- "Array length returned by " +
261
- "getAllThreadIds() = %1$d not matched count = ${provided}" ,
262
- ()->list .length
263
- );
235
+ private static void checkThreadIds (int numNewThreads , int numTerminatedThreads ) {
236
+ int threadCount = mbean .getAllThreadIds ().length ;
237
+ int expectedThreadCount = numNewThreads - numTerminatedThreads ;
238
+ if (threadCount < expectedThreadCount ) {
239
+ testFailed = true ;
240
+ System .err .println (MessageFormat .format ("Unexpected number of threads %d." +
241
+ "The expected number is %d or greater" , threadCount , expectedThreadCount ));
242
+ }
264
243
}
265
244
266
- /**
267
- * Waits till the <em>expectedVal</em> equals to the <em>retrievedVal</em>.
268
- * It will report a status message on the first occasion of the value mismatch
269
- * and then, subsequently, when the <em>retrievedVal</em> value changes.
270
- * @param expectedVal The value to wait for
271
- * @param retrievedVal The supplier of the value to check against the <em>expectedVal</em>
272
- * @param msgFormat The formatted message to be printed in case of mismatch
273
- * @param msgArgs The parameters to the formatted message
274
- * @throws InterruptedException
275
- */
276
- private static void waitTillEquals (long expectedVal , Supplier <Long > retrievedVal ,
277
- String msgFormat , Supplier <Object > ... msgArgs )
278
- throws InterruptedException {
279
- Object [] args = null ;
280
-
281
- long countPrev = -1 ;
282
- while (true ) {
283
- Long count = retrievedVal .get ();
284
- if (count == expectedVal ) break ;
285
- if (countPrev == -1 || countPrev != count ) {
286
- if (args == null ) {
287
- args = new Object [msgArgs .length ];
288
- for (int i =0 ; i < msgArgs .length ; i ++) {
289
- args [i ] = new ArgWrapper <>((Supplier <Object >)msgArgs [i ]);
290
- }
291
- }
292
- System .err .format ("TS: %s\n " , Instant .now ());
293
- System .err .format (
294
- msgFormat
295
- .replace ("${provided}" , String .valueOf (count ))
296
- .replace ("$d" , "$s" ),
297
- args
298
- ).flush ();
299
- printThreadList ();
300
- System .err .println ("\n Retrying ...\n " );
301
- }
302
- countPrev = count ;
303
- Thread .sleep (1 );
304
- }
245
+ private static long getTestThreadCount () {
246
+ return Thread .getAllStackTraces ().keySet ().stream ().filter (
247
+ thread -> thread .isAlive () && allThreadIds .contains (thread .getId ())).count ();
305
248
}
306
249
307
250
private static void updateCounters () {
308
251
prevTotalThreadCount = mbean .getTotalStartedThreadCount ();
309
- prevLiveThreadCount = mbean . getThreadCount ();
252
+ prevLiveTestThreadCount = getTestThreadCount ();
310
253
prevPeakThreadCount = mbean .getPeakThreadCount ();
311
254
}
312
255
0 commit comments