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 mbean.getThreadCount() 28 * mbean.getTotalStartedThreadCount() 29 * mbean.getPeakThreadCount() 30 * mbean.getDaemonThreadCount() 31 * @author Alexei Guibadoulline 32 * 33 * @modules java.management 34 * @run main ThreadCounts 35 */ 36 37 import java.lang.management.*; 38 39 public class ThreadCounts { 40 static final int DAEMON_THREADS = 21; 41 static final int USER_THREADS_1 = 11; 42 static final int USER_THREADS_2 = 9; 43 static final int USER_THREADS = USER_THREADS_1 + USER_THREADS_2; 44 static final int ALL_THREADS = DAEMON_THREADS + USER_THREADS; 45 private static volatile boolean live[] = new boolean[ALL_THREADS]; 46 private ThreadMXBean mbean = ManagementFactory.getThreadMXBean(); 47 private static boolean testFailed = false; 48 49 // barrier for threads communication 50 private static Barrier barrier = new Barrier(DAEMON_THREADS); 51 52 public static void main(String argv[]) { 53 ThreadCounts test = new ThreadCounts(); 54 Thread allThreads[] = new Thread[ALL_THREADS]; 55 56 // Start DAEMON_THREADS threads and wait to be sure they all are alive 57 barrier.set(DAEMON_THREADS); 58 for (int i = 0; i < DAEMON_THREADS; i++) { 59 live[i] = true; 60 allThreads[i] = new MyThread(i); 61 allThreads[i].setDaemon(true); 62 allThreads[i].start(); 63 } 64 // wait until all threads have started. 65 barrier.await(); 66 67 68 System.out.println("Number of daemon threads added = " + 69 DAEMON_THREADS); 70 // Check mbean now 71 if ( (!test.checkCount (DAEMON_THREADS)) || 72 (!test.checkCreated(DAEMON_THREADS)) || 73 (!test.checkPeak (DAEMON_THREADS)) || 74 (!test.checkDaemon (DAEMON_THREADS)) 75 ) 76 testFailed = true; 77 78 // Start USER_THREADS_1 threads and wait to be sure they all are alive 79 barrier.set(USER_THREADS_1); 80 for (int i = DAEMON_THREADS; i < DAEMON_THREADS + USER_THREADS_1; i++) { 81 live[i] = true; 82 allThreads[i] = new MyThread(i); 83 allThreads[i].setDaemon(false); 84 allThreads[i].start(); 85 } 86 // wait until user1 threads have started. 87 barrier.await(); 88 89 System.out.println("Number of threads added = " + 90 USER_THREADS_1); 91 // Check mbean now 92 if ( (!test.checkCount (DAEMON_THREADS + USER_THREADS_1)) || 93 (!test.checkCreated(DAEMON_THREADS + USER_THREADS_1)) || 94 (!test.checkPeak (DAEMON_THREADS + USER_THREADS_1)) || 95 (!test.checkDaemon (DAEMON_THREADS)) 96 ) 97 testFailed = true; 98 99 // Stop daemon threads and wait to be sure they all are dead 100 barrier.set(DAEMON_THREADS); 101 for (int i = 0; i < DAEMON_THREADS; i++) { 102 live[i] = false; 103 } 104 // wait until daemon threads terminated. 105 barrier.await(); 106 107 System.out.println("Daemon threads terminated."); 108 // Check mbean now 109 if ( (!test.checkCount (USER_THREADS_1)) || 110 (!test.checkCreated(DAEMON_THREADS + USER_THREADS_1)) || 111 (!test.checkPeak (DAEMON_THREADS + USER_THREADS_1)) || 112 (!test.checkDaemon (0)) 113 ) 114 testFailed = true; 115 116 // Start USER_THREADS_2 threads and wait to be sure they all are alive 117 barrier.set(USER_THREADS_2); 118 for (int i = DAEMON_THREADS + USER_THREADS_1; i < ALL_THREADS; i++) { 119 live[i] = true; 120 allThreads[i] = new MyThread(i); 121 allThreads[i].setDaemon(false); 122 allThreads[i].start(); 123 } 124 // wait until user2 threads have started. 125 barrier.await(); 126 127 System.out.println("Number of threads added = " + 128 USER_THREADS_2); 129 // Check mbean now 130 if ( (!test.checkCount (USER_THREADS_1 + USER_THREADS_2)) || 131 (!test.checkCreated(ALL_THREADS)) || 132 (!test.checkPeak (DAEMON_THREADS + USER_THREADS_1)) || 133 (!test.checkDaemon (0)) 134 ) 135 testFailed = true; 136 137 // Stop user1 threads and wait to be sure they all are dead 138 barrier.set(USER_THREADS_1); 139 for (int i = DAEMON_THREADS; i < DAEMON_THREADS + USER_THREADS_1; i++) { 140 live[i] = false; 141 } 142 // wait until user1 threads terminated. 143 barrier.await(); 144 145 System.out.println("Number of threads terminated = " + 146 USER_THREADS_1); 147 // Check mbean now 148 if ( (!test.checkCount (USER_THREADS_2)) || 149 (!test.checkCreated(ALL_THREADS)) || 150 (!test.checkPeak (DAEMON_THREADS + USER_THREADS_1)) || 151 (!test.checkDaemon (0)) 152 ) 153 testFailed = true; 154 155 // Stop user2 threads and wait to be sure they all are dead 156 barrier.set(USER_THREADS_2); 157 for (int i = DAEMON_THREADS + USER_THREADS_1; i < ALL_THREADS; i++) { 158 live[i] = false; 159 } 160 // wait until user2 threads terminated. 161 barrier.await(); 162 163 System.out.println("Number of threads terminated = " + 164 USER_THREADS_2); 165 // Check mbean now 166 if ( (!test.checkCount (0)) || 167 (!test.checkCreated(ALL_THREADS)) || 168 (!test.checkPeak (DAEMON_THREADS + USER_THREADS_1)) || 169 (!test.checkDaemon (0)) 170 ) 171 testFailed = true; 172 173 if (testFailed) 174 throw new RuntimeException("TEST FAILED."); 175 176 System.out.println("Test passed."); 177 } 178 179 // Nobody knows how many threads are in the JVM in the exact moment. The 180 // only thing to check for sure is minimal number of threads alive (or 181 // created) in the application 182 private boolean checkCount(long min) { 183 long result = mbean.getThreadCount(); 184 185 if (result < min) { 186 System.err.println("TEST FAILED: " + 187 "Minimal number of live threads is " + 188 min + 189 ". ThreadMXBean.getThreadCount() returned " + 190 result); 191 return false; 192 } 193 return true; 194 } 195 196 private boolean checkCreated(long min) { 197 long result = mbean.getTotalStartedThreadCount(); 198 199 if (result < min) { 200 System.err.println("TEST FAILED: " + 201 "Minimal number of created threads is " + 202 min + 203 ". ThreadMXBean.getTotalStartedThreadCount() "+ 204 "returned " + result); 205 return false; 206 } 207 return true; 208 } 209 210 private boolean checkPeak(long min) { 211 long result = mbean.getPeakThreadCount(); 212 213 if (result < min) { 214 System.err.println("TEST FAILED: " + 215 "Minimal peak thread count is " + 216 min + 217 ". ThreadMXBean.getPeakThreadCount() "+ 218 "returned " + result); 219 return false; 220 } 221 return true; 222 } 223 224 private boolean checkDaemon(long min) { 225 long result = mbean.getDaemonThreadCount(); 226 227 if (result < min) { 228 System.err.println("TEST FAILED: " + 229 "Minimal number of daemon thread count is " + 230 min + 231 "ThreadMXBean.getDaemonThreadCount() returned " 232 + result); 233 return false; 234 } 235 return true; 236 } 237 238 // The MyThread thread lives as long as correspondent live[i] value is true 239 private static class MyThread extends Thread { 240 int id; 241 242 MyThread(int id) { 243 this.id = id; 244 } 245 246 public void run() { 247 // signal started 248 barrier.signal(); 249 while (live[id]) { 250 try { 251 sleep(100); 252 } catch (InterruptedException e) { 253 System.out.println("Unexpected exception is thrown."); 254 e.printStackTrace(System.out); 255 testFailed = true; 256 } 257 } 258 // signal about to exit 259 barrier.signal(); 260 } 261 } 262 }