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