threadgroup.java

来自「《移动Agent技术》一书的所有章节源代码。」· Java 代码 · 共 842 行 · 第 1/2 页

JAVA
842
字号
     * @return  the number of thread groups put into the array.
     * @see     java.lang.ThreadGroup#activeGroupCount()
     * @since   JDK1.0
     */
    public int enumerate(ThreadGroup list[]) {
	return enumerate(list, 0, true);
    }

    /**
     * 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>
     * 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.
     * @see     java.lang.ThreadGroup#activeGroupCount()
     * @since   JDK1.0
     */
    public int enumerate(ThreadGroup list[], boolean recurse) {
	return enumerate(list, 0, recurse);
    }

    private int enumerate(ThreadGroup list[], int n, boolean recurse) {
	int ngroupsSnapshot = 0;
	ThreadGroup[] groupsSnapshot = null;
	synchronized (this) {
	    if (destroyed) {
		return 0;
	    }
	    int ng = ngroups;
	    if (ng > list.length - n) {
		ng = list.length - n;
	    }
	    if (ng > 0) {
		System.arraycopy(groups, 0, list, n, ng);
		n += ng;
	    }
	    if (recurse) {
		ngroupsSnapshot = ngroups;
		if (groups != null) {
		    groupsSnapshot = new ThreadGroup[ngroupsSnapshot];
		    System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot);
		} else {
		    groupsSnapshot = null;
		}
	    }
	}
	if (recurse) {
	    for (int i = 0 ; i < ngroupsSnapshot ; i++) {
		n = groupsSnapshot[i].enumerate(list, n, true);
	    }
	}
	return n;
    }

    /**
     * Stops all processes 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>stop</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.SecurityException
     * @see        java.lang.Thread#stop()
     * @see        java.lang.ThreadGroup#checkAccess()
     * @since      JDK1.0
     */
    public final void stop() {
	int ngroupsSnapshot;
	ThreadGroup[] groupsSnapshot;
	synchronized (this) {
	    checkAccess();
	    for (int i = 0 ; i < nthreads ; i++) {
		threads[i].stop();
	    }
	    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].stop();
	}
    }

    /**
     * Suspends all processes 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>suspend</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.SecurityException
     * @see        java.lang.Thread#suspend()
     * @see        java.lang.ThreadGroup#checkAccess()
     * @since      JDK1.0
     */
    public final void suspend() {
	int ngroupsSnapshot;
	ThreadGroup[] groupsSnapshot;
	synchronized (this) {
	    checkAccess();
	    for (int i = 0 ; i < nthreads ; i++) {
		threads[i].suspend();
	    }
	    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].suspend();
	}
    }

    /**
     * Resumes all processes 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>resume</code> method on all the
     * threads in this thread group and in all of its sub groups.
     *
     * @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.SecurityException
     * @see        java.lang.Thread#resume()
     * @see        java.lang.ThreadGroup#checkAccess()
     * @since      JDK1.0
     */
    public final void resume() {
	int ngroupsSnapshot;
	ThreadGroup[] groupsSnapshot;
	synchronized (this) {
	    checkAccess();
	    for (int i = 0 ; i < nthreads ; i++) {
		threads[i].resume();
	    }
	    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].resume();
	}
    }

    /**
     * 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.
     *
     * @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.
     * @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);
	}
    }

    /**
     * Adds the specified Thread group to this group.
     * @param g the specified Thread group to be added
     * @exception IllegalThreadStateException If the Thread group has been destroyed.
     */
    private final void add(ThreadGroup g){
	synchronized (this) {
	    if (destroyed) {
		throw new IllegalThreadStateException();
	    }
	    if (groups == null) {
		groups = new ThreadGroup[4];
	    } else if (ngroups == groups.length) {
		ThreadGroup newgroups[] = new ThreadGroup[ngroups * 2];
		System.arraycopy(groups, 0, newgroups, 0, ngroups);
		groups = newgroups;
	    }
	    groups[ngroups] = g;

	    // This is done last so it doesn't matter in case the
	    // thread is killed
	    ngroups++;
	}
    }

    /**
     * Removes the specified Thread group from this group.
     * @param g the Thread group to be removed
     * @return if this Thread has already been destroyed.
     */
    private void remove(ThreadGroup g) {
	synchronized (this) {
	    if (destroyed) {
		return;
	    }
	    for (int i = 0 ; i < ngroups ; i++) {
		if (groups[i] == g) {
		    ngroups -= 1;
		    System.arraycopy(groups, i + 1, groups, i, ngroups - i);
		    // Zap dangling reference to the dead group so that
		    // the garbage collector will collect it.
		    groups[ngroups] = null;
		    break;
		}
	    }
	    if (nthreads == 0) {
		notifyAll();
	    }
	    if (daemon && (nthreads == 0) && (ngroups == 0)) {
		destroy();
	    }
	}
    }

    /**
     * Adds the specified Thread to this group.
     * @param t the Thread to be added
     * @exception IllegalThreadStateException If the Thread group has been destroyed.
     */
    void add(Thread t) {
	synchronized (this) {
	    if (destroyed) {
		throw new IllegalThreadStateException();
	    }
	    if (threads == null) {
		threads = new Thread[4];
	    } else if (nthreads == threads.length) {
		Thread newthreads[] = new Thread[nthreads * 2];
		System.arraycopy(threads, 0, newthreads, 0, nthreads);
		threads = newthreads;
	    }
	    threads[nthreads] = t;

	    // This is done last so it doesn't matter in case the
	    // thread is killed
	    nthreads++;
	}
    }

    /**
     * Removes the specified Thread from this group.
     * @param t the Thread to be removed
     * @return if the Thread has already been destroyed.
     */
    void remove(Thread t) {
	synchronized (this) {
	    if (destroyed) {
		return;
	    }
	    for (int i = 0 ; i < nthreads ; i++) {
		if (threads[i] == t) {
		    System.arraycopy(threads, i + 1, threads, i, --nthreads - i);
		    // Zap dangling reference to the dead thread so that
		    // the garbage collector will collect it.
		    threads[nthreads] = null;
		    break;
		}
	    }
	    if (nthreads == 0) {
		notifyAll();
	    }
	    if (daemon && (nthreads == 0) && (ngroups == 0)) {
		destroy();
	    }
	}
    }

    /**
     * Prints information about this thread group to the standard
     * output. This method is useful only for debugging.
     *
     * @since   JDK1.0
     */
    public void list() {
	list(System.out, 0);
    }
    void list(PrintStream out, int indent) {
	int ngroupsSnapshot;
	ThreadGroup[] groupsSnapshot;
	synchronized (this) {
	    for (int j = 0 ; j < indent ; j++) {
		out.print(" ");
	    }
	    out.println(this);
	    indent += 4;
	    for (int i = 0 ; i < nthreads ; i++) {
		for (int j = 0 ; j < indent ; j++) {
		    out.print(" ");
		}
		out.println(threads[i]);
	    }
	    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].list(out, indent);
	}
    }

    /**
     * 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)) {
	    e.printStackTrace(System.err);
	}
    }

    /**
     * Used by VM to control lowmem implicit suspension.
     *
     * @since   JDK1.1
     */
    public boolean allowThreadSuspension(boolean b) {
	this.vmAllowSuspension = b;
	if (!b) {
	    VM.unsuspendSomeThreads();
	}
	return true;
    }

    /**
     * Returns a string representation of this Thread group.
     *
     * @return  a string representation of this thread group.
     * @since   JDK1.0
     */
    public String toString() {
	return getClass().getName() + "[name=" + getName() + ",maxpri=" + maxPriority + "]";
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?