0N/A/*
3261N/A * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A/*
0N/A * @test
0N/A * @bug 4530538
0N/A * @summary Basic unit test of ThreadMXBean.getAllThreadIds()
0N/A * @author Alexei Guibadoulline and Mandy Chung
0N/A *
0N/A * @run build Barrier
2495N/A * @run main/othervm AllThreadIds
0N/A */
0N/A
0N/Aimport java.lang.management.*;
0N/Aimport java.util.*;
0N/A
0N/Apublic class AllThreadIds {
0N/A final static int DAEMON_THREADS = 20;
0N/A final static int USER_THREADS = 5;
0N/A final static int ALL_THREADS = DAEMON_THREADS + USER_THREADS;
0N/A private static volatile boolean live[] = new boolean[ALL_THREADS];
0N/A private static Thread allThreads[] = new Thread[ALL_THREADS];
0N/A private static ThreadMXBean mbean
0N/A = ManagementFactory.getThreadMXBean();
0N/A private static boolean testFailed = false;
0N/A private static boolean trace = false;
0N/A
0N/A private static long prevTotalThreadCount = 0;
0N/A private static int prevLiveThreadCount = 0;
0N/A private static int prevPeakThreadCount = 0;
0N/A private static long curTotalThreadCount = 0;
0N/A private static int curLiveThreadCount = 0;
0N/A private static int curPeakThreadCount = 0;
0N/A
0N/A // barrier for threads communication
0N/A private static Barrier barrier = new Barrier(ALL_THREADS);
0N/A
0N/A private static void printThreadList() {
0N/A if (!trace) return;
0N/A
0N/A long[] list = mbean.getAllThreadIds();
0N/A for (int i = 1; i <= list.length; i++) {
0N/A System.out.println(i + ": Thread id = " + list[i-1]);
0N/A }
0N/A for (int i = 0; i < ALL_THREADS; i++) {
0N/A Thread t = allThreads[i];
0N/A System.out.println(t.getName() + " Id = " + t.getId() +
0N/A " die = " + live[i] +
0N/A " alive = " + t.isAlive());
0N/A }
0N/A }
0N/A
2495N/A private static void fail(String msg) {
2495N/A trace = true;
2495N/A printThreadList();
2495N/A throw new RuntimeException(msg);
2495N/A }
2495N/A
0N/A private static void checkThreadCount(int numNewThreads,
0N/A int numTerminatedThreads)
0N/A throws Exception {
0N/A prevTotalThreadCount = curTotalThreadCount;
0N/A prevLiveThreadCount = curLiveThreadCount;
0N/A prevPeakThreadCount = curPeakThreadCount;
0N/A curTotalThreadCount = mbean.getTotalStartedThreadCount();
0N/A curLiveThreadCount = mbean.getThreadCount();
0N/A curPeakThreadCount = mbean.getPeakThreadCount();
0N/A
0N/A if ((curLiveThreadCount - prevLiveThreadCount) !=
0N/A (numNewThreads - numTerminatedThreads)) {
2495N/A fail("Unexpected number of live threads: " +
2495N/A " Prev live = " + prevLiveThreadCount +
2495N/A " Current live = " + curLiveThreadCount +
0N/A " Threads added = " + numNewThreads +
0N/A " Threads terminated = " + numTerminatedThreads);
0N/A }
0N/A if (curPeakThreadCount - prevPeakThreadCount != numNewThreads) {
2495N/A fail("Unexpected number of peak threads: " +
2495N/A " Prev peak = " + prevPeakThreadCount +
2495N/A " Current peak = " + curPeakThreadCount +
0N/A " Threads added = " + numNewThreads);
0N/A }
0N/A if (curTotalThreadCount - prevTotalThreadCount != numNewThreads) {
2495N/A fail("Unexpected number of total threads: " +
0N/A " Prev Total = " + prevTotalThreadCount +
0N/A " Current Total = " + curTotalThreadCount +
0N/A " Threads added = " + numNewThreads);
0N/A }
0N/A long[] list = mbean.getAllThreadIds();
0N/A if (list.length != curLiveThreadCount) {
2495N/A fail("Array length returned by " +
0N/A "getAllThreadIds() = " + list.length +
0N/A " not matched count = " + curLiveThreadCount);
0N/A }
0N/A }
0N/A
0N/A public static void main(String args[]) throws Exception {
0N/A if (args.length > 0 && args[0].equals("trace")) {
0N/A trace = true;
0N/A }
0N/A
0N/A curTotalThreadCount = mbean.getTotalStartedThreadCount();
0N/A curLiveThreadCount = mbean.getThreadCount();
0N/A curPeakThreadCount = mbean.getPeakThreadCount();
0N/A checkThreadCount(0, 0);
0N/A
0N/A
0N/A // Start all threads and wait to be sure they all are alive
0N/A barrier.set(ALL_THREADS);
0N/A for (int i = 0; i < ALL_THREADS; i++) {
0N/A live[i] = true;
0N/A allThreads[i] = new MyThread(i);
0N/A allThreads[i].setDaemon( (i < DAEMON_THREADS) ? true : false);
0N/A allThreads[i].start();
0N/A }
0N/A // wait until all threads are started.
0N/A barrier.await();
0N/A
0N/A
0N/A checkThreadCount(ALL_THREADS, 0);
0N/A printThreadList();
0N/A
0N/A // Check mbean now. All threads must appear in getAllThreadIds() list
0N/A long[] list = mbean.getAllThreadIds();
0N/A
0N/A for (int i = 0; i < ALL_THREADS; i++) {
0N/A long expectedId = allThreads[i].getId();
0N/A boolean found = false;
0N/A
0N/A if (trace) {
0N/A System.out.print("Looking for thread with id " + expectedId);
0N/A }
0N/A for (int j = 0; j < list.length; j++) {
0N/A if (expectedId == list[j]) {
0N/A found = true;
0N/A break;
0N/A }
0N/A }
0N/A
0N/A if (!found) {
0N/A testFailed = true;
0N/A }
0N/A if (trace) {
0N/A if (!found) {
0N/A System.out.print(". TEST FAILED.");
0N/A }
0N/A System.out.println();
0N/A }
0N/A }
0N/A if (trace) {
0N/A System.out.println();
0N/A }
0N/A
0N/A // Stop daemon threads, wait to be sure they all are dead, and check
0N/A // that they disappeared from getAllThreadIds() list
0N/A barrier.set(DAEMON_THREADS);
0N/A for (int i = 0; i < DAEMON_THREADS; i++) {
0N/A live[i] = false;
0N/A }
0N/A // wait until daemon threads are terminated.
0N/A barrier.await();
0N/A
0N/A // give chance to threads to terminate
0N/A pause();
0N/A checkThreadCount(0, DAEMON_THREADS);
0N/A
0N/A // Check mbean now
0N/A list = mbean.getAllThreadIds();
0N/A
0N/A for (int i = 0; i < ALL_THREADS; i++) {
0N/A long expectedId = allThreads[i].getId();
0N/A boolean found = false;
0N/A boolean live = (i >= DAEMON_THREADS);
0N/A
0N/A if (trace) {
0N/A System.out.print("Looking for thread with id " + expectedId +
0N/A (live ? " expected alive." : " expected terminated."));
0N/A }
0N/A for (int j = 0; j < list.length; j++) {
0N/A if (expectedId == list[j]) {
0N/A found = true;
0N/A break;
0N/A }
0N/A }
0N/A
0N/A if (live != found) {
0N/A testFailed = true;
0N/A }
0N/A if (trace) {
0N/A if (live != found) {
0N/A System.out.println(" TEST FAILED.");
0N/A } else {
0N/A System.out.println();
0N/A }
0N/A }
0N/A }
0N/A
0N/A // Stop all threads and wait to be sure they all are dead
0N/A barrier.set(ALL_THREADS - DAEMON_THREADS);
0N/A for (int i = DAEMON_THREADS; i < ALL_THREADS; i++) {
0N/A live[i] = false;
0N/A }
0N/A // wait until daemon threads are terminated .
0N/A barrier.await();
0N/A
0N/A // give chance to threads to terminate
0N/A pause();
0N/A checkThreadCount(0, ALL_THREADS - DAEMON_THREADS);
0N/A
0N/A if (testFailed)
0N/A throw new RuntimeException("TEST FAILED.");
0N/A
0N/A System.out.println("Test passed.");
0N/A }
0N/A
0N/A // The MyThread thread lives as long as correspondent live[i] value is true
0N/A private static class MyThread extends Thread {
0N/A int id;
0N/A
0N/A MyThread(int id) {
0N/A this.id = id;
0N/A }
0N/A
0N/A public void run() {
0N/A // signal started
0N/A barrier.signal();
0N/A while (live[id]) {
0N/A try {
0N/A sleep(100);
0N/A } catch (InterruptedException e) {
0N/A System.out.println("Unexpected exception is thrown.");
0N/A e.printStackTrace(System.out);
0N/A testFailed = true;
0N/A }
0N/A }
0N/A // signal about to exit
0N/A barrier.signal();
0N/A }
0N/A }
0N/A
0N/A private static Object pauseObj = new Object();
0N/A private static void pause() {
0N/A // Enter lock a without blocking
0N/A synchronized (pauseObj) {
0N/A try {
0N/A // may need to tune this timeout for different platforms
0N/A pauseObj.wait(50);
0N/A } catch (Exception e) {
0N/A System.err.println("Unexpected exception.");
0N/A e.printStackTrace(System.err);
0N/A }
0N/A }
0N/A }
0N/A
0N/A}