ThreadCounts.java revision 12745:f068a4ffddd2
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
37import java.lang.management.*;
38
39public 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}
263