Source for gnu.java.lang.management.ThreadMXBeanImpl

   1: /* ThreadMXBeanImpl.java - Implementation of a thread bean
   2:    Copyright (C) 2006 Free Software Foundation
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: package gnu.java.lang.management;
  39: 
  40: import gnu.classpath.SystemProperties;
  41: 
  42: import java.lang.management.ThreadInfo;
  43: import java.lang.management.ThreadMXBean;
  44: 
  45: import javax.management.NotCompliantMBeanException;
  46: 
  47: /**
  48:  * Provides access to information about the threads
  49:  * of the virtual machine.  An instance of this bean is
  50:  * obtained by calling
  51:  * {@link ManagementFactory#getThreadMXBean()}.
  52:  * See {@link java.lang.management.ThreadMXBean} for
  53:  * full documentation.
  54:  *
  55:  * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
  56:  * @since 1.5
  57:  */
  58: public final class ThreadMXBeanImpl
  59:   extends BeanImpl
  60:   implements ThreadMXBean
  61: {
  62: 
  63:   /**
  64:    * Constant for current thread time support.
  65:    */
  66:   private static final String CURRENT_THREAD_TIME_SUPPORT =
  67:     "gnu.java.lang.management.CurrentThreadTimeSupport";
  68: 
  69:   /**
  70:    * Constant for thread time support.
  71:    */
  72:   private static final String THREAD_TIME_SUPPORT =
  73:     "gnu.java.lang.management.ThreadTimeSupport";
  74: 
  75:   /**
  76:    * Constant for thread contention support.
  77:    */
  78:   private static final String CONTENTION_SUPPORT =
  79:     "gnu.java.lang.management.ThreadContentionSupport";
  80: 
  81:   /**
  82:    * Constant for initial value of thread time support.
  83:    */
  84:   private static final String TIME_ENABLED =
  85:     "gnu.java.lang.management.ThreadTimeInitallyEnabled";
  86: 
  87:   /**
  88:    * Constant for monitor usage monitoring support.
  89:    */
  90:   private static final String MONITOR_SUPPORT =
  91:     "gnu.java.lang.management.MonitorUsageMonitoringSupport";
  92: 
  93:   /**
  94:    * Constant for ownable synchronizer usage monitoring support.
  95:    */
  96:   private static final String SYNCHRONIZER_SUPPORT =
  97:     "gnu.java.lang.management.OwnableSynchronizerUsageMonitoringSupport";
  98: 
  99:   /**
 100:    * Flag to indicate whether time monitoring is enabled or not.
 101:    */
 102:   private boolean timeEnabled;
 103: 
 104:   /**
 105:    * Flag to indicate whether contention monitoring is enabled or not.
 106:    */
 107:   private boolean contentionEnabled;
 108: 
 109:   /**
 110:    * Default constructor to set up flag states.  The
 111:    * VM has to specify whether time monitoring is initially
 112:    * enabled or not.
 113:    *
 114:    * @throws NotCompliantMBeanException if this class doesn't implement
 115:    *                                    the interface or a method appears
 116:    *                                    in the interface that doesn't comply
 117:    *                                    with the naming conventions.
 118:    */
 119:   public ThreadMXBeanImpl()
 120:     throws NotCompliantMBeanException
 121:   {
 122:     super(ThreadMXBean.class);
 123:     timeEnabled = Boolean.parseBoolean(SystemProperties.getProperty(TIME_ENABLED));
 124:     contentionEnabled = false;
 125:   }
 126: 
 127:   public ThreadInfo[] dumpAllThreads(boolean lockedMonitors,
 128:                                      boolean lockedSynchronizers)
 129:   {
 130:     return getThreadInfo(getAllThreadIds(), lockedMonitors,
 131:                          lockedSynchronizers);
 132:   }
 133: 
 134:   public long[] findDeadlockedThreads()
 135:   {
 136:     checkMonitorPermissions();
 137:     if (!isSynchronizerUsageSupported())
 138:       throw new UnsupportedOperationException("Ownable synchronizer usage " +
 139:                                               "monitoring is not provided " +
 140:                                               "by this VM.");
 141:     return VMThreadMXBeanImpl.findDeadlockedThreads();
 142:   }
 143: 
 144:   public long[] findMonitorDeadlockedThreads()
 145:   {
 146:     checkMonitorPermissions();
 147:     return VMThreadMXBeanImpl.findMonitorDeadlockedThreads();
 148:   }
 149: 
 150:   public long[] getAllThreadIds()
 151:   {
 152:     checkMonitorPermissions();
 153:     return VMThreadMXBeanImpl.getAllThreadIds();
 154:   }
 155: 
 156:   public long getCurrentThreadCpuTime()
 157:   {
 158:     if (!isCurrentThreadCpuTimeSupported())
 159:       throw new UnsupportedOperationException("Current thread CPU " +
 160:                                               "time not supported.");
 161:     if (!timeEnabled)
 162:       return -1;
 163:     return VMThreadMXBeanImpl.getCurrentThreadCpuTime();
 164:   }
 165: 
 166:   public long getCurrentThreadUserTime()
 167:   {
 168:     if (!isCurrentThreadCpuTimeSupported())
 169:       throw new UnsupportedOperationException("Current thread user " +
 170:                                               "time not supported.");
 171:     if (!timeEnabled)
 172:       return -1;
 173:     return VMThreadMXBeanImpl.getCurrentThreadUserTime();
 174:   }
 175: 
 176:   public int getDaemonThreadCount()
 177:   {
 178:     return VMThreadMXBeanImpl.getDaemonThreadCount();
 179:   }
 180: 
 181:   public int getPeakThreadCount()
 182:   {
 183:     return VMThreadMXBeanImpl.getPeakThreadCount();
 184:   }
 185: 
 186:   public int getThreadCount()
 187:   {
 188:     return VMThreadMXBeanImpl.getThreadCount();
 189:   }
 190: 
 191:   public long getThreadCpuTime(long id)
 192:   {
 193:     if (!isThreadCpuTimeSupported())
 194:       throw new UnsupportedOperationException("Thread CPU time not " +
 195:                                               "supported.");
 196:     if (id <= 0)
 197:       throw new IllegalArgumentException("Invalid thread id: " + id);
 198:     if (!timeEnabled)
 199:       return -1;
 200:     return VMThreadMXBeanImpl.getThreadCpuTime(id);
 201:   }
 202: 
 203:   public ThreadInfo getThreadInfo(long id)
 204:   {
 205:     return getThreadInfo(id, 0);
 206:   }
 207: 
 208:   public ThreadInfo[] getThreadInfo(long[] ids)
 209:   {
 210:     return getThreadInfo(ids, 0);
 211:   }
 212: 
 213:   public ThreadInfo getThreadInfo(long id, int maxDepth)
 214:   {
 215:     checkMonitorPermissions();
 216:     if (id <= 0)
 217:       throw new IllegalArgumentException("Invalid thread id: " + id);
 218:     if (maxDepth < 0)
 219:       throw new IllegalArgumentException("Invalid depth: " + maxDepth);
 220:     return VMThreadMXBeanImpl.getThreadInfoForId(id, maxDepth);
 221:   }
 222: 
 223:   public ThreadInfo[] getThreadInfo(long[] ids, int maxDepth)
 224:   {
 225:     checkMonitorPermissions();
 226:     if (maxDepth < 0)
 227:       throw new IllegalArgumentException("Invalid depth: " + maxDepth);
 228:     ThreadInfo[] infos = new ThreadInfo[ids.length];
 229:     for (int a = 0; a < ids.length; ++a)
 230:       {
 231:         if (ids[a] <= 0)
 232:           throw new IllegalArgumentException("Invalid thread id " + a +
 233:                                              ": " + ids[a]);
 234:         infos[a] = VMThreadMXBeanImpl.getThreadInfoForId(ids[a], maxDepth);
 235:       }
 236:     return infos;
 237:   }
 238: 
 239:   public ThreadInfo[] getThreadInfo(long[] ids, boolean lockedMonitors,
 240:                                     boolean lockedSynchronizers)
 241:   {
 242:     checkMonitorPermissions();
 243:     if (lockedMonitors && !isObjectMonitorUsageSupported())
 244:       throw new UnsupportedOperationException("Monitor usage monitoring is " +
 245:                                               "not provided by this VM.");
 246:     if (lockedSynchronizers && !isSynchronizerUsageSupported())
 247:       throw new UnsupportedOperationException("Ownable synchronizer usage " +
 248:                                               "monitoring is not provided " +
 249:                                               "by this VM.");
 250:     ThreadInfo[] infos = getThreadInfo(ids, Integer.MAX_VALUE);
 251:     if (lockedMonitors)
 252:       for (ThreadInfo info : infos)
 253:         VMThreadMXBeanImpl.getMonitorInfo(info);
 254:     if (lockedSynchronizers)
 255:       for (ThreadInfo info : infos)
 256:         VMThreadMXBeanImpl.getLockInfo(info);
 257:     return infos;
 258:   }
 259: 
 260:   public long getThreadUserTime(long id)
 261:   {
 262:     if (!isThreadCpuTimeSupported())
 263:       throw new UnsupportedOperationException("Thread user time not " +
 264:                                               "supported.");
 265:     if (id <= 0)
 266:       throw new IllegalArgumentException("Invalid thread id: " + id);
 267:     if (!timeEnabled)
 268:       return -1;
 269:     return VMThreadMXBeanImpl.getThreadUserTime(id);
 270:   }
 271: 
 272:   public long getTotalStartedThreadCount()
 273:   {
 274:     return VMThreadMXBeanImpl.getTotalStartedThreadCount();
 275:   }
 276: 
 277:   public boolean isCurrentThreadCpuTimeSupported()
 278:   {
 279:     if (isThreadCpuTimeSupported())
 280:       return true;
 281:     return SystemProperties.getProperty(CURRENT_THREAD_TIME_SUPPORT) != null;
 282:   }
 283: 
 284:   public boolean isObjectMonitorUsageSupported()
 285:   {
 286:     return SystemProperties.getProperty(MONITOR_SUPPORT) != null;
 287:   }
 288: 
 289:   public boolean isSynchronizerUsageSupported()
 290:   {
 291:     return SystemProperties.getProperty(SYNCHRONIZER_SUPPORT) != null;
 292:   }
 293: 
 294:   public boolean isThreadContentionMonitoringEnabled()
 295:   {
 296:     if (isThreadContentionMonitoringSupported())
 297:       return contentionEnabled;
 298:     else
 299:       throw new UnsupportedOperationException("Contention monitoring " +
 300:                                               "not supported.");
 301:   }
 302: 
 303:   public boolean isThreadContentionMonitoringSupported()
 304:   {
 305:     return SystemProperties.getProperty(CONTENTION_SUPPORT) != null;
 306:   }
 307: 
 308:   public boolean isThreadCpuTimeEnabled()
 309:   {
 310:     if (isThreadCpuTimeSupported() ||
 311:         isCurrentThreadCpuTimeSupported())
 312:       return timeEnabled;
 313:     else
 314:       throw new UnsupportedOperationException("Thread time not " +
 315:                                               "supported.");
 316:   }
 317: 
 318:   public boolean isThreadCpuTimeSupported()
 319:   {
 320:     return SystemProperties.getProperty(THREAD_TIME_SUPPORT) != null;
 321:   }
 322: 
 323:   public void resetPeakThreadCount()
 324:   {
 325:     checkControlPermissions();
 326:     VMThreadMXBeanImpl.resetPeakThreadCount();
 327:   }
 328: 
 329:   public void setThreadContentionMonitoringEnabled(boolean enable)
 330:   {
 331:     checkControlPermissions();
 332:     if (isThreadContentionMonitoringSupported())
 333:       contentionEnabled = enable;
 334:     else
 335:       throw new UnsupportedOperationException("Contention monitoring " +
 336:                                               "not supported.");
 337:   }
 338: 
 339:   public void setThreadCpuTimeEnabled(boolean enable)
 340:   {
 341:     checkControlPermissions();
 342:     if (isThreadCpuTimeSupported() ||
 343:         isCurrentThreadCpuTimeSupported())
 344:       timeEnabled = enable;
 345:     else
 346:       throw new UnsupportedOperationException("Thread time not " +
 347:                                               "supported.");
 348:   }
 349: 
 350: }