Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/lang/management/ThreadMXBean/SynchronizerLockingThread.java
41152 views
1
/*
2
* Copyright (c) 2005, 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
* @bug 5086470 6358247
26
* @summary SynchronizersLockingThread is used by LockedSynchronizers.
27
* It will create threads that acquire ReentrantLock and also object
28
* monitors.
29
* @author Mandy Chung
30
*
31
* @build ThreadDump Utils
32
*/
33
34
import java.lang.management.*;
35
import java.util.*;
36
import java.util.concurrent.locks.ReentrantLock;
37
import java.util.concurrent.locks.Condition;
38
39
public class SynchronizerLockingThread extends Thread {
40
static ReentrantLock lock1 = new ReentrantLock();
41
static ReentrantLock lock2 = new ReentrantLock();
42
static ReentrantLock lock3 = new ReentrantLock();
43
static ReentrantLock lock4 = new ReentrantLock();
44
static Lock lock5 = new Lock("lock5");
45
static Lock lock6 = new Lock("lock6");
46
static Lock lock7 = new Lock("lock7");
47
static ReentrantLock lock8 = new ReentrantLock();
48
49
static SynchronizerLockingThread t1 = new Thread1();
50
static SynchronizerLockingThread t2 = new Thread2();
51
static int count = 2;
52
static void startLockingThreads() {
53
t1.setDaemon(true);
54
t2.setDaemon(true);
55
t1.start();
56
t2.start();
57
58
// wait until t1 and t2 waits
59
while (count != 0) {
60
try {
61
Thread.sleep(100);
62
} catch (InterruptedException e) {
63
throw new RuntimeException(e);
64
}
65
}
66
67
Utils.waitForBlockWaitingState(t1);
68
Utils.waitForBlockWaitingState(t2);
69
}
70
71
static long[] getThreadIds() {
72
return new long[] {t1.getId(), t2.getId()};
73
}
74
75
static void checkLocks(ThreadInfo[] tinfos) throws Exception {
76
int matches = 0;
77
for (ThreadInfo info : tinfos) {
78
if (info.getThreadId() == t1.getId()) {
79
t1.checkLocks(info);
80
matches++;
81
}
82
if (info.getThreadId() == t2.getId()) {
83
t2.checkLocks(info);
84
matches++;
85
}
86
}
87
if (matches != 2) {
88
throw new RuntimeException("MonitorInfo missing");
89
}
90
}
91
92
static class Lock {
93
String name;
94
Lock(String name) {
95
this.name = name;
96
}
97
public String toString() {
98
return name;
99
}
100
}
101
102
final String threadName;
103
Lock waitingLock;
104
int numOwnedMonitors;
105
Map<String, Lock[]> ownedMonitors;
106
Condition waitingSync;
107
int numOwnedSyncs;
108
Map<String, ReentrantLock[]> ownedSyncs;
109
public SynchronizerLockingThread(String name) {
110
this.threadName = name;
111
}
112
113
protected void setExpectedResult(Lock waitingLock,
114
int numOwnedMonitors,
115
Map<String, Lock[]> ownedMonitors,
116
Condition waitingSync,
117
int numOwnedSyncs,
118
Map<String, ReentrantLock[]> ownedSyncs) {
119
this.waitingLock = waitingLock;
120
this.numOwnedMonitors = numOwnedMonitors;
121
this.ownedMonitors = ownedMonitors;
122
this.waitingSync = waitingSync;
123
this.numOwnedSyncs = numOwnedSyncs;
124
this.ownedSyncs = ownedSyncs;
125
}
126
127
void checkLocks(ThreadInfo info) throws Exception {
128
checkThreadInfo(info);
129
MonitorInfo[] monitors = info.getLockedMonitors();
130
if (monitors.length != numOwnedMonitors) {
131
ThreadDump.threadDump();
132
throw new RuntimeException("Number of locked monitors = " +
133
monitors.length +
134
" not matched. Expected: " + numOwnedMonitors);
135
}
136
// check if each monitor returned in the list is the expected
137
// one
138
for (MonitorInfo m : monitors) {
139
StackTraceElement ste = m.getLockedStackFrame();
140
int depth = m.getLockedStackDepth();
141
checkStackFrame(info, ste, depth);
142
checkMonitor(m, ste.getMethodName());
143
}
144
// check if each expected monitor is included in the returned
145
// list
146
for (Map.Entry<String, Lock[]> e : ownedMonitors.entrySet()) {
147
for (Lock l : e.getValue()) {
148
checkMonitor(e.getKey(), l, monitors);
149
}
150
}
151
152
// We can only check if the length matches since we have no
153
// way to get the AbstractOwnableSynchronizer in ReentrantLock
154
LockInfo[] syncs = info.getLockedSynchronizers();
155
if (syncs.length != numOwnedSyncs) {
156
ThreadDump.threadDump();
157
throw new RuntimeException("Number of locked syncs = " +
158
syncs.length +
159
" not matched. Expected: " + numOwnedSyncs);
160
}
161
}
162
163
void checkThreadInfo(ThreadInfo info) throws Exception {
164
if (!getName().equals(info.getThreadName())) {
165
throw new RuntimeException("Name: " + info.getThreadName() +
166
" not matched. Expected: " + getName());
167
}
168
LockInfo l = info.getLockInfo();
169
if ((waitingLock != null || waitingSync != null) && l == null) {
170
throw new RuntimeException("LockInfo: " + l +
171
" not matched. Expected: non-null");
172
}
173
if (waitingLock == null && waitingSync == null && l != null) {
174
throw new RuntimeException("LockInfo: " + l +
175
" not matched. Expected: null");
176
}
177
178
String waitingLockName;
179
int hcode;
180
if (waitingLock != null) {
181
waitingLockName = waitingLock.getClass().getName();
182
hcode = System.identityHashCode(waitingLock);
183
} else {
184
waitingLockName = waitingSync.getClass().getName();
185
hcode = System.identityHashCode(waitingSync);
186
}
187
if (!waitingLockName.equals(l.getClassName())) {
188
throw new RuntimeException("LockInfo : " + l +
189
" class name not matched. Expected: " + waitingLockName);
190
}
191
if (hcode != l.getIdentityHashCode()) {
192
throw new RuntimeException("LockInfo: " + l +
193
" IdentityHashCode not matched. Expected: " + hcode);
194
}
195
196
String lockName = info.getLockName();
197
String[] s = lockName.split("@");
198
if (!waitingLockName.equals(s[0])) {
199
throw new RuntimeException("LockName: " + lockName +
200
" class name not matched. Expected: " + waitingLockName);
201
}
202
int i = Integer.parseInt(s[1], 16);
203
if (hcode != i) {
204
throw new RuntimeException("LockName: " + lockName +
205
" IdentityHashCode not matched. Expected: " + hcode);
206
}
207
}
208
209
void checkStackFrame(ThreadInfo info, StackTraceElement ste, int depth) {
210
StackTraceElement[] stacktrace = info.getStackTrace();
211
if (!ste.equals(stacktrace[depth])) {
212
System.out.println("LockedStackFrame:- " + ste);
213
System.out.println("StackTrace at " + depth + " :-" +
214
stacktrace[depth]);
215
throw new RuntimeException("LockedStackFrame does not match " +
216
"stack frame in ThreadInfo.getStackTrace");
217
}
218
}
219
void checkMonitor(MonitorInfo m, String methodName) {
220
for (Map.Entry<String, Lock[]> e : ownedMonitors.entrySet()) {
221
if (methodName.equals(e.getKey())) {
222
for (Lock l : e.getValue()) {
223
String className = l.getClass().getName();
224
int hcode = System.identityHashCode(l);
225
if (className.equals(m.getClassName()) &&
226
hcode == m.getIdentityHashCode()) {
227
// monitor matched the expected
228
return;
229
}
230
}
231
}
232
}
233
throw new RuntimeException("Monitor not expected" + m);
234
}
235
void checkMonitor(String methodName, Lock l, MonitorInfo[] monitors) {
236
String className = l.getClass().getName();
237
int hcode = System.identityHashCode(l);
238
for (MonitorInfo m : monitors) {
239
if (className.equals(m.getClassName()) &&
240
hcode == m.getIdentityHashCode() &&
241
methodName.equals(m.getLockedStackFrame().getMethodName())) {
242
return;
243
}
244
}
245
throw new RuntimeException("Monitor not found in the returned list" +
246
" Method: " + methodName + " Lock: " + l);
247
248
}
249
250
static class Thread1 extends SynchronizerLockingThread {
251
public Thread1() {
252
super("t1");
253
initExpectedResult();
254
}
255
public void run() {
256
A();
257
}
258
void A() {
259
lock1.lock();
260
try {
261
lock2.lock();
262
try {
263
lock3.lock();
264
try {
265
B();
266
} finally {
267
lock3.unlock();
268
}
269
} finally {
270
lock2.unlock();
271
}
272
} finally {
273
lock1.unlock();
274
}
275
}
276
void B() {
277
lock4.lock();
278
try {
279
synchronized(lock5) {
280
C();
281
}
282
} finally {
283
lock4.unlock();
284
}
285
}
286
void C() {
287
synchronized(lock6) {
288
D();
289
}
290
}
291
void D() {
292
synchronized(lock7) {
293
try {
294
// signal to about to wait
295
count--;
296
lock7.wait();
297
} catch (InterruptedException e) {
298
throw new RuntimeException(e);
299
}
300
}
301
}
302
303
Map<String, Lock[]> LOCKED_MONITORS;
304
Map<String, ReentrantLock[]> LOCKED_SYNCS;
305
Lock WAITING_LOCK = lock7;
306
int OWNED_MONITORS = 2;
307
int OWNED_SYNCS = 4;
308
void initExpectedResult() {
309
LOCKED_MONITORS = new HashMap<String, Lock[]>();
310
LOCKED_MONITORS.put("D", new Lock[0]); // no monitored locked
311
LOCKED_MONITORS.put("C", new Lock[] {lock6});
312
LOCKED_MONITORS.put("B", new Lock[] {lock5});
313
LOCKED_MONITORS.put("A", new Lock[0]);
314
315
LOCKED_SYNCS = new HashMap<String, ReentrantLock[]>();
316
LOCKED_SYNCS.put("D", new ReentrantLock[0]); // no sync locked
317
LOCKED_SYNCS.put("C", new ReentrantLock[0]); // no sync locked
318
LOCKED_SYNCS.put("B", new ReentrantLock[] {lock4});
319
LOCKED_SYNCS.put("A", new ReentrantLock[] {lock3, lock2, lock1});
320
this.setExpectedResult(WAITING_LOCK,
321
OWNED_MONITORS, LOCKED_MONITORS,
322
null,
323
OWNED_SYNCS, LOCKED_SYNCS);
324
}
325
326
}
327
328
static class Thread2 extends SynchronizerLockingThread {
329
Map<String, Lock[]> LOCKED_MONITORS = new HashMap<String, Lock[]>();
330
Map<String, ReentrantLock[]> LOCKED_SYNCS = new HashMap<String, ReentrantLock[]>();
331
Condition c = lock8.newCondition();
332
Condition WAITING_LOCK = c;
333
int OWNED_MONITORS = 0;
334
int OWNED_SYNCS = 0;
335
public Thread2() {
336
super("t2");
337
this.setExpectedResult(null,
338
OWNED_MONITORS, LOCKED_MONITORS,
339
WAITING_LOCK,
340
OWNED_SYNCS, LOCKED_SYNCS);
341
}
342
public void run() {
343
lock8.lock();
344
try {
345
synchronized(lock7) {
346
count--;
347
}
348
c.await();
349
} catch (InterruptedException e) {
350
throw new RuntimeException(e);
351
} finally {
352
lock8.unlock();
353
}
354
throw new RuntimeException("should not reach here");
355
}
356
}
357
358
}
359
360