/**
  * 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;
 }
示例#2
0
  /**
   * Sets the priority of this thread. If the requested priority is greater than the parent thread
   * group's {@link java.lang.ThreadGroup#getMaxPriority}, the group's maximum priority will be used
   * instead.
   *
   * @throws IllegalArgumentException - if the new priority is greater than {@link #MAX_PRIORITY} or
   *     less than {@link #MIN_PRIORITY}
   */
  public final void setPriority(int priority) {
    if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
      throw new IllegalArgumentException("Priority out of range: " + priority);
    }

    if (priority > group.getMaxPriority()) {
      priority = group.getMaxPriority();
    }

    this.priority = priority;

    VMThread vmt = this.vmThread;
    if (vmt != null) {
      vmt.setPriority(priority);
    }
  }
 /**
  * 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);
   }
 }
 /**
  * Called by the Java Virtual Machine when a thread in this thread group stops because of an
  * uncaught exception.
  *
  * <p>The <code>uncaughtException</code> method of <code>ThreadGroup</code> does the following:
  *
  * <ul>
  *   <li>If this thread group has a parent thread group, the <code>uncaughtException</code> method
  *       of that parent is called with the same two arguments.
  *   <li>Otherwise, this method determines if the <code>Throwable</code> argument is an instance
  *       of <code>ThreadDeath</code>. If so, nothing special is done. Otherwise, the <code>
  *       Throwable</code>'s <code>printStackTrace</code> method is called to print a stack
  *       backtrace to the standard error stream.
  * </ul>
  *
  * <p>Applications can override this method in subclasses of <code>ThreadGroup</code> to provide
  * alternative handling of uncaught exceptions.
  *
  * @param t the thread that is about to exit.
  * @param e the uncaught exception.
  * @see java.lang.System#err
  * @see java.lang.ThreadDeath
  * @see java.lang.Throwable#printStackTrace(java.io.PrintStream)
  * @since JDK1.0
  */
 public void uncaughtException(Thread t, Throwable e) {
   if (parent != null) {
     parent.uncaughtException(t, e);
   } else if (!(e instanceof ThreadDeath)) {
     if (System.err != null) {
       /* can be null at startup */
       e.printStackTrace(System.err);
     }
   }
 }
示例#5
0
  /**
   * Initializes a new, existing Thread object with a runnable object, the given name and belonging
   * to the ThreadGroup passed as parameter. This is the method that the several public constructors
   * delegate their work to.
   *
   * @param group ThreadGroup to which the new Thread will belong
   * @param runnable a java.lang.Runnable whose method <code>run</code> will be executed by the new
   *     Thread
   * @param threadName Name for the Thread being created
   * @param stackSize Platform dependent stack size
   * @throws IllegalThreadStateException if <code>group.destroy()</code> has already been done
   * @see java.lang.ThreadGroup
   * @see java.lang.Runnable
   */
  private void create(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
    Thread currentThread = Thread.currentThread();
    if (group == null) {
      group = currentThread.getThreadGroup();
    }

    if (group.isDestroyed()) {
      throw new IllegalThreadStateException("Group already destroyed");
    }

    this.group = group;

    synchronized (Thread.class) {
      id = ++Thread.count;
    }

    if (threadName == null) {
      this.name = "Thread-" + id;
    } else {
      this.name = threadName;
    }

    this.target = runnable;
    this.stackSize = stackSize;

    this.priority = currentThread.getPriority();

    this.contextClassLoader = currentThread.contextClassLoader;

    // Transfer over InheritableThreadLocals.
    if (currentThread.inheritableValues != null) {
      inheritableValues = new ThreadLocal.Values(currentThread.inheritableValues);
    }

    // add ourselves to our ThreadGroup of choice
    this.group.addThread(this);
  }
示例#6
0
  public static void main(String[] args) {

    ThreadGroup group = new ThreadGroup("demo");

    for (int i = 0; i < 3; i++) {
      new Thread(
              group,
              new Runnable() {
                public void run() {
                  System.out.print("");
                }
              })
          .start();
    }
    group.list();
    int count = group.activeCount(); // 获得线程组中活动的线程
    System.out.println(count);
    Thread threads[] = new Thread[group.activeCount()];
    group.enumerate(threads); // 将当前线程组中活动的线程复制到一个线程数组中去。

    for (Thread thread : threads) {
      System.out.println(thread.getName());
    }
    ThreadGroup parent = group.getParent();

    parent.list();
    ThreadGroup parent2 = parent.getParent();
    parent2.list();
  }
示例#7
0
 /**
  * Returns a string containing a concise, human-readable description of the Thread. It includes
  * the Thread's name, priority, and group name.
  *
  * @return a printable representation for the receiver.
  */
 @Override
 public String toString() {
   return "Thread[" + name + "," + priority + "," + group.getName() + "]";
 }
 /**
  * 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;
 }