/**
  * Destroys this thread group and all of its subgroups. This thread group must be empty,
  * indicating that all threads that had been in this thread group have since stopped.
  *
  * <p>First, the <code>checkAccess</code> method of this thread group is called with no arguments;
  * this may result in a security exception.
  *
  * @exception IllegalThreadStateException if the thread group is not empty or if the thread group
  *     has already been destroyed.
  * @exception SecurityException if the current thread cannot modify this thread group.
  * @see java.lang.ThreadGroup#checkAccess()
  * @since JDK1.0
  */
 public final void destroy() {
   int ngroupsSnapshot;
   ThreadGroup[] groupsSnapshot;
   synchronized (this) {
     checkAccess();
     if (destroyed || (nthreads > 0)) {
       throw new IllegalThreadStateException();
     }
     ngroupsSnapshot = ngroups;
     if (groups != null) {
       groupsSnapshot = new ThreadGroup[ngroupsSnapshot];
       System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot);
     } else {
       groupsSnapshot = null;
     }
     if (parent != null) {
       destroyed = true;
       ngroups = 0;
       groups = null;
       nthreads = 0;
       threads = null;
     }
   }
   for (int i = 0; i < ngroupsSnapshot; i += 1) {
     groupsSnapshot[i].destroy();
   }
   if (parent != null) {
     parent.remove(this);
   }
 }
 /**
  * Creates a new thread group. The parent of this new group is the specified thread group.
  *
  * <p>The <code>checkAccess</code> method of the parent thread group is called with no arguments;
  * this may result in a security exception.
  *
  * @param parent the parent thread group.
  * @param name the name of the new thread group.
  * @exception NullPointerException if the thread group argument is <code>null</code>.
  * @exception SecurityException if the current thread cannot create a thread in the specified
  *     thread group.
  * @see java.lang.SecurityException
  * @see java.lang.ThreadGroup#checkAccess()
  * @since JDK1.0
  */
 public ThreadGroup(ThreadGroup parent, String name) {
   if (parent == null) {
     throw new NullPointerException();
   }
   parent.checkAccess();
   this.name = name;
   this.maxPriority = parent.maxPriority;
   this.daemon = parent.daemon;
   this.vmAllowSuspension = parent.vmAllowSuspension;
   this.parent = parent;
   parent.add(this);
   saveThreadStarterClassFlag = parent.saveThreadStarterClassFlag;
 }
 /**
  * Interrupts all threads in this thread group.
  *
  * <p>First, the <code>checkAccess</code> method of this thread group is called with no arguments;
  * this may result in a security exception.
  *
  * <p>This method then calls the <code>interrupt</code> method on all the threads in this thread
  * group and in all of its subgroups.
  *
  * @exception SecurityException if the current thread is not allowed to access this thread group
  *     or any of the threads in the thread group.
  * @see java.lang.Thread#interrupt()
  * @see java.lang.SecurityException
  * @see java.lang.ThreadGroup#checkAccess()
  * @since 1.2
  */
 public final void interrupt() {
   int ngroupsSnapshot;
   ThreadGroup[] groupsSnapshot;
   synchronized (this) {
     checkAccess();
     for (int i = 0; i < nthreads; i++) {
       threads[i].interrupt();
     }
     ngroupsSnapshot = ngroups;
     if (groups != null) {
       groupsSnapshot = new ThreadGroup[ngroupsSnapshot];
       System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot);
     } else {
       groupsSnapshot = null;
     }
   }
   for (int i = 0; i < ngroupsSnapshot; i++) {
     groupsSnapshot[i].interrupt();
   }
 }
 /**
  * Sets the maximum priority of the group. Threads in the thread group that already have a higher
  * priority are not affected.
  *
  * <p>First, the <code>checkAccess</code> method of this thread group is called with no arguments;
  * this may result in a security exception.
  *
  * <p>If the <code>pri</code> argument is less than {@link Thread#MIN_PRIORITY} or greater than
  * {@link Thread#MAX_PRIORITY}, the maximum priority of the group remains unchanged.
  *
  * <p>Otherwise, the priority of this ThreadGroup object is set to the smaller of the specified
  * <code>pri</code> and the maximum permitted priority of the parent of this thread group. (If
  * this thread group is the system thread group, which has no parent, then its maximum priority is
  * simply set to <code>pri</code>.) Then this method is called recursively, with <code>pri</code>
  * as its argument, for every thread group that belongs to this thread group.
  *
  * @param pri the new priority of the thread group.
  * @exception SecurityException if the current thread cannot modify this thread group.
  * @see #getMaxPriority
  * @see java.lang.SecurityException
  * @see java.lang.ThreadGroup#checkAccess()
  * @since JDK1.0
  */
 public final void setMaxPriority(int pri) {
   int ngroupsSnapshot;
   ThreadGroup[] groupsSnapshot;
   synchronized (this) {
     checkAccess();
     if (pri < Thread.MIN_PRIORITY) {
       maxPriority = Thread.MIN_PRIORITY;
     } else if (pri < maxPriority) {
       maxPriority = pri;
     }
     ngroupsSnapshot = ngroups;
     if (groups != null) {
       groupsSnapshot = new ThreadGroup[ngroupsSnapshot];
       System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot);
     } else {
       groupsSnapshot = null;
     }
   }
   for (int i = 0; i < ngroupsSnapshot; i++) {
     groupsSnapshot[i].setMaxPriority(pri);
   }
 }
 /**
  * Copies into the specified array references to every active subgroup in this thread group. If
  * the <code>recurse</code> flag is <code>true</code>, references to all active subgroups of the
  * subgroups and so forth are also included.
  *
  * <p>First, the <code>checkAccess</code> method of this thread group is called with no arguments;
  * this may result in a security exception.
  *
  * <p>An application should use the <code>activeGroupCount</code> method to get an estimate of how
  * big the array should be.
  *
  * @param list an array into which to place the list of threads.
  * @param recurse a flag indicating whether to recursively enumerate all included thread groups.
  * @return the number of thread groups put into the array.
  * @exception SecurityException if the current thread does not have permission to enumerate this
  *     thread group.
  * @see java.lang.ThreadGroup#activeGroupCount()
  * @see java.lang.ThreadGroup#checkAccess()
  * @since JDK1.0
  */
 public int enumerate(ThreadGroup list[], boolean recurse) {
   checkAccess();
   return enumerate(list, 0, recurse);
 }
 /**
  * Copies into the specified array references to every active subgroup in this thread group.
  *
  * <p>First, the <code>checkAccess</code> method of this thread group is called with no arguments;
  * this may result in a security exception.
  *
  * <p>An application should use the <code>activeGroupCount</code> method to get an estimate of how
  * big the array should be. If the array is too short to hold all the thread groups, the extra
  * thread groups are silently ignored.
  *
  * @param list an array into which to place the list of thread groups.
  * @return the number of thread groups put into the array.
  * @exception SecurityException if the current thread does not have permission to enumerate this
  *     thread group.
  * @see java.lang.ThreadGroup#activeGroupCount()
  * @see java.lang.ThreadGroup#checkAccess()
  * @since JDK1.0
  */
 public int enumerate(ThreadGroup list[]) {
   checkAccess();
   return enumerate(list, 0, true);
 }
 /**
  * Changes the daemon status of this thread group.
  *
  * <p>First, the <code>checkAccess</code> method of this thread group is called with no arguments;
  * this may result in a security exception.
  *
  * <p>A daemon thread group is automatically destroyed when its last thread is stopped or its last
  * thread group is destroyed.
  *
  * @param daemon if <code>true</code>, marks this thread group as a daemon thread group;
  *     otherwise, marks this thread group as normal.
  * @exception SecurityException if the current thread cannot modify this thread group.
  * @see java.lang.SecurityException
  * @see java.lang.ThreadGroup#checkAccess()
  * @since JDK1.0
  */
 public final void setDaemon(boolean daemon) {
   checkAccess();
   this.daemon = daemon;
 }
 /**
  * Returns the parent of this thread group.
  *
  * <p>First, if the parent is not <code>null</code>, the <code>checkAccess</code> method of the
  * parent thread group is called with no arguments; this may result in a security exception.
  *
  * @return the parent of this thread group. The top-level thread group is the only thread group
  *     whose parent is <code>null</code>.
  * @exception SecurityException if the current thread cannot modify this thread group.
  * @see java.lang.ThreadGroup#checkAccess()
  * @see java.lang.SecurityException
  * @see java.lang.RuntimePermission
  * @since JDK1.0
  */
 public final ThreadGroup getParent() {
   if (parent != null) parent.checkAccess();
   return parent;
 }