blob: 50b34151dedf4442e0d554ba1ace4902fce73aa0 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2003-2004 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/*
25 * @test
26 * @bug 4530538
27 * @summary Basic unit test of ThreadMXBean.getAllThreadIds()
28 * @author Alexei Guibadoulline and Mandy Chung
29 *
30 * @run build Barrier
31 * @run main AllThreadIds
32 */
33
34import java.lang.management.*;
35import java.util.*;
36
37public class AllThreadIds {
38 final static int DAEMON_THREADS = 20;
39 final static int USER_THREADS = 5;
40 final static int ALL_THREADS = DAEMON_THREADS + USER_THREADS;
41 private static volatile boolean live[] = new boolean[ALL_THREADS];
42 private static Thread allThreads[] = new Thread[ALL_THREADS];
43 private static ThreadMXBean mbean
44 = ManagementFactory.getThreadMXBean();
45 private static boolean testFailed = false;
46 private static boolean trace = false;
47
48 private static long prevTotalThreadCount = 0;
49 private static int prevLiveThreadCount = 0;
50 private static int prevPeakThreadCount = 0;
51 private static long curTotalThreadCount = 0;
52 private static int curLiveThreadCount = 0;
53 private static int curPeakThreadCount = 0;
54
55 // barrier for threads communication
56 private static Barrier barrier = new Barrier(ALL_THREADS);
57
58 private static void printThreadList() {
59 if (!trace) return;
60
61 long[] list = mbean.getAllThreadIds();
62 for (int i = 1; i <= list.length; i++) {
63 System.out.println(i + ": Thread id = " + list[i-1]);
64 }
65 for (int i = 0; i < ALL_THREADS; i++) {
66 Thread t = allThreads[i];
67 System.out.println(t.getName() + " Id = " + t.getId() +
68 " die = " + live[i] +
69 " alive = " + t.isAlive());
70 }
71 }
72
73 private static void checkThreadCount(int numNewThreads,
74 int numTerminatedThreads)
75 throws Exception {
76 prevTotalThreadCount = curTotalThreadCount;
77 prevLiveThreadCount = curLiveThreadCount;
78 prevPeakThreadCount = curPeakThreadCount;
79 curTotalThreadCount = mbean.getTotalStartedThreadCount();
80 curLiveThreadCount = mbean.getThreadCount();
81 curPeakThreadCount = mbean.getPeakThreadCount();
82
83 if ((curLiveThreadCount - prevLiveThreadCount) !=
84 (numNewThreads - numTerminatedThreads)) {
85 throw new RuntimeException("Unexpected number of live threads: " +
86 " Prev Total = " + prevTotalThreadCount +
87 " Current Total = " + curTotalThreadCount +
88 " Threads added = " + numNewThreads +
89 " Threads terminated = " + numTerminatedThreads);
90 }
91 if (curPeakThreadCount - prevPeakThreadCount != numNewThreads) {
92 throw new RuntimeException("Unexpected number of peak threads: " +
93 " Prev Total = " + prevTotalThreadCount +
94 " Current Total = " + curTotalThreadCount +
95 " Threads added = " + numNewThreads);
96 }
97 if (curTotalThreadCount - prevTotalThreadCount != numNewThreads) {
98 throw new RuntimeException("Unexpected number of total threads: " +
99 " Prev Total = " + prevTotalThreadCount +
100 " Current Total = " + curTotalThreadCount +
101 " Threads added = " + numNewThreads);
102 }
103 long[] list = mbean.getAllThreadIds();
104 if (list.length != curLiveThreadCount) {
105 throw new RuntimeException("Array length returned by " +
106 "getAllThreadIds() = " + list.length +
107 " not matched count = " + curLiveThreadCount);
108 }
109 }
110
111 public static void main(String args[]) throws Exception {
112 if (args.length > 0 && args[0].equals("trace")) {
113 trace = true;
114 }
115
116 curTotalThreadCount = mbean.getTotalStartedThreadCount();
117 curLiveThreadCount = mbean.getThreadCount();
118 curPeakThreadCount = mbean.getPeakThreadCount();
119 checkThreadCount(0, 0);
120
121
122 // Start all threads and wait to be sure they all are alive
123 barrier.set(ALL_THREADS);
124 for (int i = 0; i < ALL_THREADS; i++) {
125 live[i] = true;
126 allThreads[i] = new MyThread(i);
127 allThreads[i].setDaemon( (i < DAEMON_THREADS) ? true : false);
128 allThreads[i].start();
129 }
130 // wait until all threads are started.
131 barrier.await();
132
133
134 checkThreadCount(ALL_THREADS, 0);
135 printThreadList();
136
137 // Check mbean now. All threads must appear in getAllThreadIds() list
138 long[] list = mbean.getAllThreadIds();
139
140 for (int i = 0; i < ALL_THREADS; i++) {
141 long expectedId = allThreads[i].getId();
142 boolean found = false;
143
144 if (trace) {
145 System.out.print("Looking for thread with id " + expectedId);
146 }
147 for (int j = 0; j < list.length; j++) {
148 if (expectedId == list[j]) {
149 found = true;
150 break;
151 }
152 }
153
154 if (!found) {
155 testFailed = true;
156 }
157 if (trace) {
158 if (!found) {
159 System.out.print(". TEST FAILED.");
160 }
161 System.out.println();
162 }
163 }
164 if (trace) {
165 System.out.println();
166 }
167
168 // Stop daemon threads, wait to be sure they all are dead, and check
169 // that they disappeared from getAllThreadIds() list
170 barrier.set(DAEMON_THREADS);
171 for (int i = 0; i < DAEMON_THREADS; i++) {
172 live[i] = false;
173 }
174 // wait until daemon threads are terminated.
175 barrier.await();
176
177 // give chance to threads to terminate
178 pause();
179 checkThreadCount(0, DAEMON_THREADS);
180
181 // Check mbean now
182 list = mbean.getAllThreadIds();
183
184 for (int i = 0; i < ALL_THREADS; i++) {
185 long expectedId = allThreads[i].getId();
186 boolean found = false;
187 boolean live = (i >= DAEMON_THREADS);
188
189 if (trace) {
190 System.out.print("Looking for thread with id " + expectedId +
191 (live ? " expected alive." : " expected terminated."));
192 }
193 for (int j = 0; j < list.length; j++) {
194 if (expectedId == list[j]) {
195 found = true;
196 break;
197 }
198 }
199
200 if (live != found) {
201 testFailed = true;
202 }
203 if (trace) {
204 if (live != found) {
205 System.out.println(" TEST FAILED.");
206 } else {
207 System.out.println();
208 }
209 }
210 }
211
212 // Stop all threads and wait to be sure they all are dead
213 barrier.set(ALL_THREADS - DAEMON_THREADS);
214 for (int i = DAEMON_THREADS; i < ALL_THREADS; i++) {
215 live[i] = false;
216 }
217 // wait until daemon threads are terminated .
218 barrier.await();
219
220 // give chance to threads to terminate
221 pause();
222 checkThreadCount(0, ALL_THREADS - DAEMON_THREADS);
223
224 if (testFailed)
225 throw new RuntimeException("TEST FAILED.");
226
227 System.out.println("Test passed.");
228 }
229
230 // The MyThread thread lives as long as correspondent live[i] value is true
231 private static class MyThread extends Thread {
232 int id;
233
234 MyThread(int id) {
235 this.id = id;
236 }
237
238 public void run() {
239 // signal started
240 barrier.signal();
241 while (live[id]) {
242 try {
243 sleep(100);
244 } catch (InterruptedException e) {
245 System.out.println("Unexpected exception is thrown.");
246 e.printStackTrace(System.out);
247 testFailed = true;
248 }
249 }
250 // signal about to exit
251 barrier.signal();
252 }
253 }
254
255 private static Object pauseObj = new Object();
256 private static void pause() {
257 // Enter lock a without blocking
258 synchronized (pauseObj) {
259 try {
260 // may need to tune this timeout for different platforms
261 pauseObj.wait(50);
262 } catch (Exception e) {
263 System.err.println("Unexpected exception.");
264 e.printStackTrace(System.err);
265 }
266 }
267 }
268
269}