1 /* 2 * Copyright (c) 2005, 2006, 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 6222826 6379712 27 * @summary Test that all monitors will be well started when sharing 28 * a single thread pool. 29 * @author Luis-Miguel Alventosa 30 * @run clean ThreadPoolTest 31 * @run build ThreadPoolTest 32 * @run main/othervm/timeout=300 ThreadPoolTest 1 33 * @run main/othervm/timeout=300 ThreadPoolTest 2 34 * @run main/othervm/timeout=300 ThreadPoolTest 3 35 * @run main/othervm/timeout=300 -Djmx.x.monitor.maximum.pool.size=5 ThreadPoolTest 1 36 * @run main/othervm/timeout=300 -Djmx.x.monitor.maximum.pool.size=5 ThreadPoolTest 2 37 * @run main/othervm/timeout=300 -Djmx.x.monitor.maximum.pool.size=5 ThreadPoolTest 3 38 * @run main/othervm/timeout=300 -Djmx.x.monitor.maximum.pool.size=-5 ThreadPoolTest 1 39 * @run main/othervm/timeout=300 -Djmx.x.monitor.maximum.pool.size=-5 ThreadPoolTest 2 40 * @run main/othervm/timeout=300 -Djmx.x.monitor.maximum.pool.size=-5 ThreadPoolTest 3 41 */ 42 43 import java.util.concurrent.atomic.AtomicInteger; 44 import javax.management.MBeanServer; 45 import javax.management.MBeanServerFactory; 46 import javax.management.Notification; 47 import javax.management.NotificationListener; 48 import javax.management.ObjectName; 49 import javax.management.monitor.CounterMonitor; 50 import javax.management.monitor.GaugeMonitor; 51 import javax.management.monitor.Monitor; 52 import javax.management.monitor.MonitorNotification; 53 import javax.management.monitor.StringMonitor; 54 55 public class ThreadPoolTest { 56 57 static int maxPoolSize; 58 static int nTasks; 59 private static Waiter waiter; 60 61 static final long MAX_WAITING_TIME = 10000; 62 63 // MBean class 64 public class ObservedObject implements ObservedObjectMBean { 65 private boolean called = false; 66 public Integer getInteger() { 67 inform("getInteger()"); 68 return 0; 69 } 70 public Double getDouble() { 71 inform("getDouble()"); 72 return 0.0; 73 } 74 public String getString() { 75 inform("getString()"); 76 return ""; 77 } 78 private void inform(String prop) { 79 synchronized(waiter) { 80 if (!called) { 81 called = true; 82 waiter.count(); 83 } 84 } 85 86 echo(">>> TASK "+prop+" is called."); 87 } 88 } 89 90 // MBean interface 91 public interface ObservedObjectMBean { 92 public Integer getInteger(); 93 public Double getDouble(); 94 public String getString(); 95 } 96 97 /** 98 * Run test 99 */ 100 public int runTest(int monitorType) throws Exception { 101 102 103 ObjectName[] mbeanNames = new ObjectName[nTasks]; 104 ObservedObject[] monitored = new ObservedObject[nTasks]; 105 ObjectName[] monitorNames = new ObjectName[nTasks]; 106 Monitor[] monitor = new Monitor[nTasks]; 107 String[] attributes = { "Integer", "Double", "String" }; 108 109 try { 110 echo(">>> CREATE MBeanServer"); 111 MBeanServer server = MBeanServerFactory.newMBeanServer(); 112 113 String domain = server.getDefaultDomain(); 114 115 for (int i = 0; i < nTasks; i++) { 116 mbeanNames[i] = 117 new ObjectName(":type=ObservedObject,instance=" + (i + 1)); 118 monitored[i] = new ObservedObject(); 119 echo(">>> CREATE ObservedObject = " + mbeanNames[i].toString()); 120 server.registerMBean(monitored[i], mbeanNames[i]); 121 switch (monitorType) { 122 case 1: 123 monitorNames[i] = new ObjectName(":type=CounterMonitor," + 124 "instance=" + (i + 1)); 125 monitor[i] = new CounterMonitor(); 126 break; 127 case 2: 128 monitorNames[i] = new ObjectName(":type=GaugeMonitor," + 129 "instance=" + (i + 1)); 130 monitor[i] = new GaugeMonitor(); 131 break; 132 case 3: 133 monitorNames[i] = new ObjectName(":type=StringMonitor," + 134 "instance=" + (i + 1)); 135 monitor[i] = new StringMonitor(); 136 break; 137 default: 138 echo("Unsupported monitor type"); 139 return 1; 140 } 141 echo(">>> CREATE Monitor = " + monitorNames[i].toString()); 142 server.registerMBean(monitor[i], monitorNames[i]); 143 monitor[i].addObservedObject(mbeanNames[i]); 144 monitor[i].setObservedAttribute(attributes[monitorType-1]); 145 monitor[i].setGranularityPeriod(50); 146 monitor[i].start(); 147 } 148 149 if (!waiter.waiting(MAX_WAITING_TIME)) { 150 echo("Error, not all "+nTasks+" monitor tasks are called after " 151 +MAX_WAITING_TIME); 152 return 1; 153 } 154 } finally { 155 for (int i = 0; i < nTasks; i++) 156 if (monitor[i] != null) 157 monitor[i].stop(); 158 } 159 160 echo("All "+nTasks+" monitors are called."); 161 return 0; 162 } 163 164 /* 165 * Print message 166 */ 167 private static void echo(String message) { 168 System.out.println(message); 169 } 170 171 /* 172 * Standalone entry point. 173 * 174 * Run the test and report to stdout. 175 */ 176 public static void main (String args[]) throws Exception { 177 Integer size = Integer.getInteger("jmx.x.monitor.maximum.pool.size"); 178 if (size == null) { 179 maxPoolSize = 10; 180 echo(">>> MAXIMUM POOL SIZE = 10 [default value]"); 181 } else { 182 maxPoolSize = size.intValue() < 1 ? 1 : size.intValue(); 183 echo(">>> MAXIMUM POOL SIZE = " + maxPoolSize); 184 } 185 186 nTasks = maxPoolSize + 2; 187 waiter = new Waiter(nTasks); 188 ThreadPoolTest test = new ThreadPoolTest(); 189 190 int error = test.runTest(Integer.parseInt(args[0])); 191 if (error > 0) { 192 echo(">>> Unhappy Bye, Bye!"); 193 throw new IllegalStateException( 194 "Test FAILED: Unexpected Maximum Pool Size Overflow!"); 195 } else { 196 echo(">>> Happy Bye, Bye!"); 197 } 198 } 199 200 private static class Waiter { 201 public Waiter(int waitedNB) { 202 this.waitedNB = waitedNB; 203 } 204 205 public void count() { 206 synchronized(this) { 207 counted++; 208 209 if (counted == waitedNB) { 210 this.notifyAll(); 211 } 212 } 213 } 214 215 public boolean waiting(long timeout) { 216 final long startTime = System.currentTimeMillis(); 217 long toWait = timeout; 218 219 synchronized(this) { 220 while(counted < waitedNB && toWait > 0) { 221 try { 222 this.wait(toWait); 223 } catch (InterruptedException ire) { 224 break; 225 } 226 227 toWait = timeout - 228 (System.currentTimeMillis() - startTime); 229 } 230 } 231 232 return counted == waitedNB; 233 } 234 235 private int waitedNB; 236 private int counted = 0; 237 } 238 }