Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/lang/management/ThreadMXBean/SynchronizationStatistics.java
41152 views
1
/*
2
* Copyright (c) 2003, 2015, 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 4530538
27
* @summary Basic unit test of the synchronization statistics support:
28
* @author Mandy Chung
29
* @author Jaroslav Bachorik
30
*
31
* @run main/othervm SynchronizationStatistics
32
*/
33
34
import java.lang.management.*;
35
import java.util.concurrent.Phaser;
36
import java.util.function.Supplier;
37
38
public class SynchronizationStatistics {
39
private static class LockerThread extends Thread {
40
public LockerThread(Runnable r) {
41
super(r, "LockerThread");
42
}
43
}
44
45
private static final ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
46
47
private static final boolean blockedTimeCheck =
48
mbean.isThreadContentionMonitoringSupported();
49
50
51
public static void main(String args[]) throws Exception {
52
if (blockedTimeCheck) {
53
mbean.setThreadContentionMonitoringEnabled(true);
54
}
55
56
if (!mbean.isThreadContentionMonitoringEnabled()) {
57
throw new RuntimeException("TEST FAILED: " +
58
"Thread Contention Monitoring is not enabled");
59
}
60
61
testBlockingOnSimpleMonitor();
62
testBlockingOnNestedMonitor();
63
testWaitingOnSimpleMonitor();
64
testMultiWaitingOnSimpleMonitor();
65
testWaitingOnNestedMonitor();
66
67
System.out.println("Test passed.");
68
}
69
70
private static LockerThread newLockerThread(Runnable r) {
71
LockerThread t = new LockerThread(r);
72
t.setDaemon(true);
73
return t;
74
}
75
76
private static void waitForThreadState(Thread t, Thread.State state) throws InterruptedException {
77
while (t.getState() != state) {
78
Thread.sleep(3);
79
}
80
}
81
82
/**
83
* Tests that blocking on a single monitor properly increases the
84
* blocked count at least by 1. Also asserts that the correct lock name is provided.
85
*/
86
private static void testBlockingOnSimpleMonitor() throws Exception {
87
System.out.println("testBlockingOnSimpleMonitor");
88
final Object lock1 = new Object();
89
System.out.println("Lock1 = " + lock1);
90
91
final Phaser p = new Phaser(2);
92
LockerThread lt = newLockerThread(new Runnable() {
93
@Override
94
public void run() {
95
p.arriveAndAwaitAdvance(); // phase[1]
96
synchronized(lock1) {
97
System.out.println("[LockerThread obtained Lock1]");
98
p.arriveAndAwaitAdvance(); // phase[2]
99
}
100
p.arriveAndAwaitAdvance(); // phase[3]
101
}
102
});
103
104
lt.start();
105
long tid = lt.getId();
106
ThreadInfo ti = mbean.getThreadInfo(tid);
107
String lockName = null;
108
synchronized(lock1) {
109
p.arriveAndAwaitAdvance(); // phase[1]
110
waitForThreadState(lt, Thread.State.BLOCKED);
111
do {
112
lockName = mbean.getThreadInfo(tid).getLockName();
113
} while (lockName == null);
114
}
115
116
p.arriveAndAwaitAdvance(); // phase[2]
117
testBlocked(ti, () -> mbean.getThreadInfo(tid), lockName, lock1);
118
p.arriveAndDeregister(); // phase[3]
119
120
lt.join();
121
122
printok();
123
}
124
125
/**
126
* Tests that blocking on a nested monitor properly increases the
127
* blocked count at least by 1 - it is not affected by the nesting depth.
128
* Also asserts that the correct lock name is provided.
129
*/
130
private static void testBlockingOnNestedMonitor() throws Exception {
131
System.out.println("testBlockingOnNestedMonitor");
132
final Object lock1 = new Object();
133
final Object lock2 = new Object();
134
135
System.out.println("Lock1 = " + lock1);
136
System.out.println("Lock2 = " + lock2);
137
138
final Phaser p = new Phaser(2);
139
LockerThread lt = newLockerThread(new Runnable() {
140
@Override
141
public void run() {
142
p.arriveAndAwaitAdvance(); // phase[1]
143
synchronized(lock1) {
144
System.out.println("[LockerThread obtained Lock1]");
145
p.arriveAndAwaitAdvance(); // phase[2]
146
p.arriveAndAwaitAdvance(); // phase[3]
147
synchronized(lock2) {
148
System.out.println("[LockerThread obtained Lock2]");
149
p.arriveAndAwaitAdvance(); // phase[4]
150
}
151
p.arriveAndAwaitAdvance(); // phase[5]
152
}
153
}
154
});
155
156
lt.start();
157
long tid = lt.getId();
158
ThreadInfo ti = mbean.getThreadInfo(tid);
159
String lockName = null;
160
synchronized(lock1) {
161
p.arriveAndAwaitAdvance(); // phase[1]
162
waitForThreadState(lt, Thread.State.BLOCKED);
163
do {
164
lockName = mbean.getThreadInfo(tid).getLockName();
165
} while (lockName == null);
166
}
167
p.arriveAndAwaitAdvance(); // phase[2]
168
169
ti = testBlocked(ti, () -> mbean.getThreadInfo(tid), lockName, lock1);
170
171
synchronized(lock2) {
172
p.arriveAndAwaitAdvance(); // phase [3]
173
waitForThreadState(lt, Thread.State.BLOCKED);
174
do {
175
lockName = mbean.getThreadInfo(tid).getLockName();
176
} while (lockName == null);
177
}
178
p.arriveAndAwaitAdvance(); // phase [4]
179
testBlocked(ti, () -> mbean.getThreadInfo(tid), lockName, lock2);
180
p.arriveAndDeregister();
181
182
lt.join();
183
184
printok();
185
}
186
187
/**
188
* Tests that waiting on a single monitor properly increases the waited
189
* count by 1 and the waited time by a positive number.
190
*/
191
private static void testWaitingOnSimpleMonitor() throws Exception {
192
System.out.println("testWaitingOnSimpleMonitor");
193
final Object lock1 = new Object();
194
final Phaser p = new Phaser(2);
195
LockerThread lt = newLockerThread(new Runnable() {
196
@Override
197
public void run() {
198
p.arriveAndAwaitAdvance(); // phase[1]
199
synchronized(lock1) {
200
System.out.println("[LockerThread obtained Lock1]");
201
try {
202
lock1.wait(300);
203
} catch (InterruptedException ex) {
204
// ignore
205
}
206
p.arriveAndAwaitAdvance(); // phase[2]
207
}
208
p.arriveAndAwaitAdvance(); // phase[3]
209
}
210
});
211
212
lt.start();
213
ThreadInfo ti1 = mbean.getThreadInfo(lt.getId());
214
synchronized(lock1) {
215
p.arriveAndAwaitAdvance(); // phase[1]
216
waitForThreadState(lt, Thread.State.BLOCKED);
217
}
218
p.arriveAndAwaitAdvance(); // phase[2]
219
220
testWaited(ti1, () -> mbean.getThreadInfo(lt.getId()), 1);
221
p.arriveAndDeregister(); // phase[3]
222
223
lt.join();
224
225
printok();
226
}
227
228
/**
229
* Tests that waiting multiple times on the same monitor subsequently
230
* increases the waited count by the number of subsequent calls and the
231
* waited time by a positive number.
232
*/
233
private static void testMultiWaitingOnSimpleMonitor() throws Exception {
234
System.out.println("testWaitingOnMultipleMonitors");
235
final Object lock1 = new Object();
236
237
final Phaser p = new Phaser(2);
238
LockerThread lt = newLockerThread(new Runnable() {
239
@Override
240
public void run() {
241
p.arriveAndAwaitAdvance(); // phase[1]
242
synchronized(lock1) {
243
System.out.println("[LockerThread obtained Lock1]");
244
for (int i = 0; i < 3; i++) {
245
try {
246
lock1.wait(300);
247
} catch (InterruptedException ex) {
248
// ignore
249
}
250
p.arriveAndAwaitAdvance(); // phase[2-4]
251
}
252
}
253
p.arriveAndAwaitAdvance(); // phase[5]
254
}
255
});
256
257
lt.start();
258
ThreadInfo ti1 = mbean.getThreadInfo(lt.getId());
259
synchronized(lock1) {
260
p.arriveAndAwaitAdvance(); //phase[1]
261
waitForThreadState(lt, Thread.State.BLOCKED);
262
}
263
int phase = p.getPhase();
264
while ((p.arriveAndAwaitAdvance() - phase) < 3); // phase[2-4]
265
266
testWaited(ti1, () -> mbean.getThreadInfo(lt.getId()), 3);
267
p.arriveAndDeregister(); // phase[5]
268
269
lt.join();
270
271
printok();
272
}
273
274
/**
275
* Tests that waiting on monitors places in nested synchronized blocks
276
* properly increases the waited count by the number of times the "lock.wait()"
277
* was invoked and the waited time by a positive number.
278
*/
279
private static void testWaitingOnNestedMonitor() throws Exception {
280
System.out.println("testWaitingOnNestedMonitor");
281
final Object lock1 = new Object();
282
final Object lock2 = new Object();
283
final Object lock3 = new Object();
284
285
final Phaser p = new Phaser(2);
286
LockerThread lt = newLockerThread(new Runnable() {
287
@Override
288
public void run() {
289
p.arriveAndAwaitAdvance(); // phase[1]
290
synchronized(lock1) {
291
System.out.println("[LockerThread obtained Lock1]");
292
try {
293
lock1.wait(300);
294
} catch (InterruptedException ex) {
295
// ignore
296
}
297
298
p.arriveAndAwaitAdvance(); // phase[2]
299
synchronized(lock2) {
300
System.out.println("[LockerThread obtained Lock2]");
301
try {
302
lock2.wait(300);
303
} catch (InterruptedException ex) {
304
// ignore
305
}
306
307
p.arriveAndAwaitAdvance(); // phase[3]
308
synchronized(lock3) {
309
System.out.println("[LockerThread obtained Lock3]");
310
try {
311
lock3.wait(300);
312
} catch (InterruptedException ex) {
313
// ignore
314
}
315
p.arriveAndAwaitAdvance(); // phase[4]
316
}
317
}
318
}
319
p.arriveAndAwaitAdvance(); // phase[5]
320
}
321
});
322
323
lt.start();
324
ThreadInfo ti1 = mbean.getThreadInfo(lt.getId());
325
synchronized(lock1) {
326
p.arriveAndAwaitAdvance(); // phase[1]
327
waitForThreadState(lt, Thread.State.BLOCKED);
328
}
329
330
synchronized(lock2) {
331
p.arriveAndAwaitAdvance(); // phase[2]
332
waitForThreadState(lt, Thread.State.BLOCKED);
333
}
334
335
synchronized(lock3) {
336
p.arriveAndAwaitAdvance(); // phase[3]
337
waitForThreadState(lt, Thread.State.BLOCKED);
338
}
339
340
p.arriveAndAwaitAdvance(); // phase[4]
341
testWaited(ti1, () -> mbean.getThreadInfo(lt.getId()), 3);
342
p.arriveAndDeregister(); // phase[5]
343
344
lt.join();
345
printok();
346
}
347
348
private static void printok() {
349
System.out.println("OK\n");
350
}
351
352
private static void testWaited(ThreadInfo ti1, Supplier<ThreadInfo> ti2, int waited)
353
throws InterruptedException {
354
boolean error;
355
do {
356
error = false;
357
ThreadInfo ti = ti2.get();
358
long waitCntDiff = ti.getWaitedCount() - ti1.getWaitedCount();
359
long waitTimeDiff = ti.getWaitedTime() - ti1.getWaitedTime();
360
if (waitCntDiff < waited) {
361
System.err.println(
362
"Unexpected diff in waited count. Expecting at least "
363
+ waited + " , got " + waitCntDiff
364
);
365
error = true;
366
}
367
if (waitTimeDiff <= 0) {
368
System.err.println(
369
"Unexpected diff in waited time. Expecting increasing " +
370
"value, got " + waitTimeDiff + "ms"
371
);
372
error = true;
373
}
374
if (error) {
375
System.err.println("Retrying in 20ms ...");
376
Thread.sleep(20);
377
}
378
} while (error);
379
}
380
381
private static ThreadInfo testBlocked(ThreadInfo ti1, Supplier<ThreadInfo> ti2,
382
String lockName, final Object lock)
383
throws InterruptedException {
384
boolean error;
385
ThreadInfo ti = null;
386
do {
387
error = false;
388
ti = ti2.get();
389
long blkCntDiff = ti.getBlockedCount() - ti1.getBlockedCount();
390
long blkTimeDiff = ti.getBlockedTime() - ti1.getBlockedTime();
391
392
System.out.println("testBlocked: [" + blkCntDiff + ", " + blkTimeDiff + ", " + lockName + "]");
393
394
if (blkCntDiff < 1) {
395
System.err.println(
396
"Unexpected diff in blocked count. Expecting at least 1, " +
397
"got " + blkCntDiff
398
);
399
error = true;
400
}
401
if (blkTimeDiff < 0) {
402
System.err.println(
403
"Unexpected diff in blocked time. Expecting a positive " +
404
"number, got " + blkTimeDiff
405
);
406
error = true;
407
}
408
if (!lockName.equals(lock.toString())) {
409
System.err.println(
410
"Unexpected blocked monitor name. Expecting " +
411
lock.toString() + ", got " + lockName
412
);
413
error = true;
414
}
415
if (error) {
416
System.err.println("Retrying in 20ms ...");
417
Thread.sleep(20);
418
}
419
} while (error);
420
return ti;
421
}
422
}
423
424