diff options
Diffstat (limited to 'libjava/java/lang/ThreadGroup.java')
-rw-r--r-- | libjava/java/lang/ThreadGroup.java | 749 |
1 files changed, 0 insertions, 749 deletions
diff --git a/libjava/java/lang/ThreadGroup.java b/libjava/java/lang/ThreadGroup.java deleted file mode 100644 index 6e4c27a7135..00000000000 --- a/libjava/java/lang/ThreadGroup.java +++ /dev/null @@ -1,749 +0,0 @@ -/* ThreadGroup -- a group of Threads - Copyright (C) 1998, 2000, 2001, 2002, 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.lang; - -import java.util.Vector; - -/** - * ThreadGroup allows you to group Threads together. There is a hierarchy - * of ThreadGroups, and only the initial ThreadGroup has no parent. A Thread - * may access information about its own ThreadGroup, but not its parents or - * others outside the tree. - * - * @author John Keiser - * @author Tom Tromey - * @author Bryce McKinlay - * @author Eric Blake (ebb9@email.byu.edu) - * @see Thread - * @since 1.0 - * @status updated to 1.4 - */ -public class ThreadGroup -{ - /** The Initial, top-level ThreadGroup. */ - static ThreadGroup root = new ThreadGroup(); - - /** - * This flag is set if an uncaught exception occurs. The runtime should - * check this and exit with an error status if it is set. - */ - static boolean had_uncaught_exception; - - /** The parent thread group. */ - private final ThreadGroup parent; - - /** The group name, non-null. */ - final String name; - - /** The threads in the group. */ - private final Vector threads = new Vector(); - - /** Child thread groups, or null when this group is destroyed. */ - private Vector groups = new Vector(); - - /** If all threads in the group are daemons. */ - private boolean daemon_flag = false; - - /** The maximum group priority. */ - private int maxpri; - - /** - * Hidden constructor to build the root node. - */ - private ThreadGroup() - { - name = "main"; - parent = null; - maxpri = Thread.MAX_PRIORITY; - } - - /** - * Create a new ThreadGroup using the given name and the current thread's - * ThreadGroup as a parent. There may be a security check, - * <code>checkAccess</code>. - * - * @param name the name to use for the ThreadGroup - * @throws SecurityException if the current thread cannot create a group - * @see #checkAccess() - */ - public ThreadGroup(String name) - { - this(Thread.currentThread().group, name); - } - - /** - * Create a new ThreadGroup using the given name and parent group. The new - * group inherits the maximum priority and daemon status of its parent - * group. There may be a security check, <code>checkAccess</code>. - * - * @param name the name to use for the ThreadGroup - * @param parent the ThreadGroup to use as a parent - * @throws NullPointerException if parent is null - * @throws SecurityException if the current thread cannot create a group - * @throws IllegalThreadStateException if the parent is destroyed - * @see #checkAccess() - */ - public ThreadGroup(ThreadGroup parent, String name) - { - parent.checkAccess(); - this.parent = parent; - this.name = name; - maxpri = parent.maxpri; - daemon_flag = parent.daemon_flag; - synchronized (parent) - { - if (parent.groups == null) - throw new IllegalThreadStateException(); - parent.groups.add(this); - } - } - - /** - * Get the name of this ThreadGroup. - * - * @return the name of this ThreadGroup - */ - public final String getName() - { - return name; - } - - /** - * Get the parent of this ThreadGroup. If the parent is not null, there - * may be a security check, <code>checkAccess</code>. - * - * @return the parent of this ThreadGroup - * @throws SecurityException if permission is denied - */ - public final ThreadGroup getParent() - { - if (parent != null) - parent.checkAccess(); - return parent; - } - - /** - * Get the maximum priority of Threads in this ThreadGroup. Threads created - * after this call in this group may not exceed this priority. - * - * @return the maximum priority of Threads in this ThreadGroup - */ - public final int getMaxPriority() - { - return maxpri; - } - - /** - * Tell whether this ThreadGroup is a daemon group. A daemon group will - * be automatically destroyed when its last thread is stopped and - * its last thread group is destroyed. - * - * @return whether this ThreadGroup is a daemon group - */ - public final boolean isDaemon() - { - return daemon_flag; - } - - /** - * Tell whether this ThreadGroup has been destroyed or not. - * - * @return whether this ThreadGroup has been destroyed or not - * @since 1.1 - */ - public synchronized boolean isDestroyed() - { - return groups == null; - } - - /** - * Set whether this ThreadGroup is a daemon group. A daemon group will be - * destroyed when its last thread is stopped and its last thread group is - * destroyed. There may be a security check, <code>checkAccess</code>. - * - * @param daemon whether this ThreadGroup should be a daemon group - * @throws SecurityException if you cannot modify this ThreadGroup - * @see #checkAccess() - */ - public final void setDaemon(boolean daemon) - { - checkAccess(); - daemon_flag = daemon; - } - - /** - * Set the maximum priority for Threads in this ThreadGroup. setMaxPriority - * can only be used to reduce the current maximum. If maxpri is greater - * than the current Maximum of the parent group, the current value is not - * changed. Otherwise, all groups which belong to this have their priority - * adjusted as well. Calling this does not affect threads already in this - * ThreadGroup. There may be a security check, <code>checkAccess</code>. - * - * @param maxpri the new maximum priority for this ThreadGroup - * @throws SecurityException if you cannot modify this ThreadGroup - * @see #getMaxPriority() - * @see #checkAccess() - */ - public final synchronized void setMaxPriority(int maxpri) - { - checkAccess(); - if (maxpri < Thread.MIN_PRIORITY || maxpri > Thread.MAX_PRIORITY) - return; - if (parent != null && maxpri > parent.maxpri) - maxpri = parent.maxpri; - this.maxpri = maxpri; - if (groups == null) - return; - int i = groups.size(); - while (--i >= 0) - ((ThreadGroup) groups.get(i)).setMaxPriority(maxpri); - } - - /** - * Check whether this ThreadGroup is an ancestor of the specified - * ThreadGroup, or if they are the same. - * - * @param group the group to test on - * @return whether this ThreadGroup is a parent of the specified group - */ - public final boolean parentOf(ThreadGroup group) - { - while (group != null) - { - if (group == this) - return true; - group = group.parent; - } - return false; - } - - /** - * Find out if the current Thread can modify this ThreadGroup. This passes - * the check on to <code>SecurityManager.checkAccess(this)</code>. - * - * @throws SecurityException if the current Thread cannot modify this - * ThreadGroup - * @see SecurityManager#checkAccess(ThreadGroup) - */ - public final void checkAccess() - { - // Bypass System.getSecurityManager, for bootstrap efficiency. - SecurityManager sm = SecurityManager.current; - if (sm != null) - sm.checkAccess(this); - } - - /** - * Return an estimate of the total number of active threads in this - * ThreadGroup and all its descendants. This cannot return an exact number, - * since the status of threads may change after they were counted; but it - * should be pretty close. Based on a JDC bug, - * <a href="http://developer.java.sun.com/developer/bugParade/bugs/4089701.html"> - * 4089701</a>, we take active to mean isAlive(). - * - * @return count of active threads in this ThreadGroup and its descendants - */ - public int activeCount() - { - int total = 0; - if (groups == null) - return total; - int i = threads.size(); - while (--i >= 0) - if (((Thread) threads.get(i)).isAlive()) - total++; - i = groups.size(); - while (--i >= 0) - total += ((ThreadGroup) groups.get(i)).activeCount(); - return total; - } - - /** - * Copy all of the active Threads from this ThreadGroup and its descendants - * into the specified array. If the array is not big enough to hold all - * the Threads, extra Threads will simply not be copied. There may be a - * security check, <code>checkAccess</code>. - * - * @param array the array to put the threads into - * @return the number of threads put into the array - * @throws SecurityException if permission was denied - * @throws NullPointerException if array is null - * @throws ArrayStoreException if a thread does not fit in the array - * @see #activeCount() - * @see #checkAccess() - * @see #enumerate(Thread[], boolean) - */ - public int enumerate(Thread[] array) - { - return enumerate(array, 0, true); - } - - /** - * Copy all of the active Threads from this ThreadGroup and, if desired, - * from its descendants, into the specified array. If the array is not big - * enough to hold all the Threads, extra Threads will simply not be copied. - * There may be a security check, <code>checkAccess</code>. - * - * @param array the array to put the threads into - * @param recurse whether to recurse into descendent ThreadGroups - * @return the number of threads put into the array - * @throws SecurityException if permission was denied - * @throws NullPointerException if array is null - * @throws ArrayStoreException if a thread does not fit in the array - * @see #activeCount() - * @see #checkAccess() - */ - public int enumerate(Thread[] array, boolean recurse) - { - return enumerate(array, 0, recurse); - } - - /** - * Get the number of active groups in this ThreadGroup. This group itself - * is not included in the count. A sub-group is active if it has not been - * destroyed. This cannot return an exact number, since the status of - * threads may change after they were counted; but it should be pretty close. - * - * @return the number of active groups in this ThreadGroup - */ - public int activeGroupCount() - { - if (groups == null) - return 0; - int total = groups.size(); - int i = total; - while (--i >= 0) - total += ((ThreadGroup) groups.get(i)).activeGroupCount(); - return total; - } - - /** - * Copy all active ThreadGroups that are descendants of this ThreadGroup - * into the specified array. If the array is not large enough to hold all - * active ThreadGroups, extra ThreadGroups simply will not be copied. There - * may be a security check, <code>checkAccess</code>. - * - * @param array the array to put the ThreadGroups into - * @return the number of ThreadGroups copied into the array - * @throws SecurityException if permission was denied - * @throws NullPointerException if array is null - * @throws ArrayStoreException if a group does not fit in the array - * @see #activeCount() - * @see #checkAccess() - * @see #enumerate(ThreadGroup[], boolean) - */ - public int enumerate(ThreadGroup[] array) - { - return enumerate(array, 0, true); - } - - /** - * Copy all active ThreadGroups that are children of this ThreadGroup into - * the specified array, and if desired, also all descendents. If the array - * is not large enough to hold all active ThreadGroups, extra ThreadGroups - * simply will not be copied. There may be a security check, - * <code>checkAccess</code>. - * - * @param array the array to put the ThreadGroups into - * @param recurse whether to recurse into descendent ThreadGroups - * @return the number of ThreadGroups copied into the array - * @throws SecurityException if permission was denied - * @throws NullPointerException if array is null - * @throws ArrayStoreException if a group does not fit in the array - * @see #activeCount() - * @see #checkAccess() - */ - public int enumerate(ThreadGroup[] array, boolean recurse) - { - return enumerate(array, 0, recurse); - } - - /** - * Stop all Threads in this ThreadGroup and its descendants. - * - * <p>This is inherently unsafe, as it can interrupt synchronized blocks and - * leave data in bad states. Hence, there is a security check: - * <code>checkAccess()</code>, followed by further checks on each thread - * being stopped. - * - * @throws SecurityException if permission is denied - * @see #checkAccess() - * @see Thread#stop(Throwable) - * @deprecated unsafe operation, try not to use - */ - public final synchronized void stop() - { - checkAccess(); - if (groups == null) - return; - int i = threads.size(); - while (--i >= 0) - ((Thread) threads.get(i)).stop(); - i = groups.size(); - while (--i >= 0) - ((ThreadGroup) groups.get(i)).stop(); - } - - /** - * Interrupt all Threads in this ThreadGroup and its sub-groups. There may - * be a security check, <code>checkAccess</code>. - * - * @throws SecurityException if permission is denied - * @see #checkAccess() - * @see Thread#interrupt() - * @since 1.2 - */ - public final synchronized void interrupt() - { - checkAccess(); - if (groups == null) - return; - int i = threads.size(); - while (--i >= 0) - ((Thread) threads.get(i)).interrupt(); - i = groups.size(); - while (--i >= 0) - ((ThreadGroup) groups.get(i)).interrupt(); - } - - /** - * Suspend all Threads in this ThreadGroup and its descendants. - * - * <p>This is inherently unsafe, as suspended threads still hold locks, - * which can lead to deadlock. Hence, there is a security check: - * <code>checkAccess()</code>, followed by further checks on each thread - * being suspended. - * - * @throws SecurityException if permission is denied - * @see #checkAccess() - * @see Thread#suspend() - * @deprecated unsafe operation, try not to use - */ - public final synchronized void suspend() - { - checkAccess(); - if (groups == null) - return; - int i = threads.size(); - while (--i >= 0) - ((Thread) threads.get(i)).suspend(); - i = groups.size(); - while (--i >= 0) - ((ThreadGroup) groups.get(i)).suspend(); - } - - /** - * Resume all suspended Threads in this ThreadGroup and its descendants. - * To mirror suspend(), there is a security check: - * <code>checkAccess()</code>, followed by further checks on each thread - * being resumed. - * - * @throws SecurityException if permission is denied - * @see #checkAccess() - * @see Thread#suspend() - * @deprecated pointless, since suspend is deprecated - */ - public final synchronized void resume() - { - checkAccess(); - if (groups == null) - return; - int i = threads.size(); - while (--i >= 0) - ((Thread) threads.get(i)).resume(); - i = groups.size(); - while (--i >= 0) - ((ThreadGroup) groups.get(i)).resume(); - } - - /** - * Destroy this ThreadGroup. The group must be empty, meaning that all - * threads and sub-groups have completed execution. Daemon groups are - * destroyed automatically. There may be a security check, - * <code>checkAccess</code>. - * - * @throws IllegalThreadStateException if the ThreadGroup is not empty, or - * was previously destroyed - * @throws SecurityException if permission is denied - * @see #checkAccess() - */ - public final synchronized void destroy() - { - checkAccess(); - if (! threads.isEmpty() || groups == null) - throw new IllegalThreadStateException(); - int i = groups.size(); - while (--i >= 0) - ((ThreadGroup) groups.get(i)).destroy(); - groups = null; - if (parent != null) - parent.removeGroup(this); - } - - /** - * Print out information about this ThreadGroup to System.out. This is - * meant for debugging purposes. <b>WARNING:</b> This method is not secure, - * and can print the name of threads to standard out even when you cannot - * otherwise get at such threads. - */ - public void list() - { - list(""); - } - - /** - * When a Thread in this ThreadGroup does not catch an exception, the - * virtual machine calls this method. The default implementation simply - * passes the call to the parent; then in top ThreadGroup, it will - * ignore ThreadDeath and print the stack trace of any other throwable. - * Override this method if you want to handle the exception in a different - * manner. - * - * @param thread the thread that exited - * @param t the uncaught throwable - * @throws NullPointerException if t is null - * @see ThreadDeath - * @see System#err - * @see Throwable#printStackTrace() - */ - public void uncaughtException(Thread thread, Throwable t) - { - if (parent != null) - parent.uncaughtException(thread, t); - else if (! (t instanceof ThreadDeath)) - { - if (t == null) - throw new NullPointerException(); - had_uncaught_exception = true; - try - { - if (thread != null) - System.err.print("Exception in thread \"" + thread.name + "\" "); - t.printStackTrace(System.err); - } - catch (Throwable x) - { - // This means that something is badly screwed up with the runtime, - // or perhaps someone overloaded the Throwable.printStackTrace to - // die. In any case, try to deal with it gracefully. - try - { - System.err.println(t); - System.err.println("*** Got " + x - + " while trying to print stack trace."); - } - catch (Throwable x2) - { - // Here, someone may have overloaded t.toString() or - // x.toString() to die. Give up all hope; we can't even chain - // the exception, because the chain would likewise die. - System.err.println("*** Catastrophic failure while handling " - + "uncaught exception."); - throw new InternalError(); - } - } - } - } - - /** - * Originally intended to tell the VM whether it may suspend Threads in - * low memory situations, this method was never implemented by Sun, and - * is hence a no-op. - * - * @param allow whether to allow low-memory thread suspension; ignored - * @return false - * @since 1.1 - * @deprecated pointless, since suspend is deprecated - */ - public boolean allowThreadSuspension(boolean allow) - { - return false; - } - - /** - * Return a human-readable String representing this ThreadGroup. The format - * of the string is:<br> - * <code>getClass().getName() + "[name=" + getName() + ",maxpri=" - * + getMaxPriority() + ']'</code>. - * - * @return a human-readable String representing this ThreadGroup - */ - public String toString() - { - return getClass().getName() + "[name=" + name + ",maxpri=" + maxpri + ']'; - } - - /** - * Implements enumerate. - * - * @param list the array to put the threads into - * @param next the next open slot in the array - * @param recurse whether to recurse into descendent ThreadGroups - * @return the number of threads put into the array - * @throws SecurityException if permission was denied - * @throws NullPointerException if list is null - * @throws ArrayStoreException if a thread does not fit in the array - * @see #enumerate(Thread[]) - * @see #enumerate(Thread[], boolean) - */ - private int enumerate(Thread[] list, int next, boolean recurse) - { - checkAccess(); - if (groups == null) - return next; - int i = threads.size(); - while (--i >= 0 && next < list.length) - { - Thread t = (Thread) threads.get(i); - if (t.isAlive()) - list[next++] = t; - } - if (recurse) - { - i = groups.size(); - while (--i >= 0 && next < list.length) - { - ThreadGroup g = (ThreadGroup) groups.get(i); - next = g.enumerate(list, next, true); - } - } - return next; - } - - /** - * Implements enumerate. - * - * @param list the array to put the groups into - * @param next the next open slot in the array - * @param recurse whether to recurse into descendent ThreadGroups - * @return the number of groups put into the array - * @throws SecurityException if permission was denied - * @throws NullPointerException if list is null - * @throws ArrayStoreException if a group does not fit in the array - * @see #enumerate(ThreadGroup[]) - * @see #enumerate(ThreadGroup[], boolean) - */ - private int enumerate(ThreadGroup[] list, int next, boolean recurse) - { - checkAccess(); - if (groups == null) - return next; - int i = groups.size(); - while (--i >= 0 && next < list.length) - { - ThreadGroup g = (ThreadGroup) groups.get(i); - list[next++] = g; - if (recurse && next != list.length) - next = g.enumerate(list, next, true); - } - return next; - } - - /** - * Implements list. - * - * @param indentation the current level of indentation - * @see #list() - */ - private void list(String indentation) - { - if (groups == null) - return; - System.out.println(indentation + this); - indentation += " "; - int i = threads.size(); - while (--i >= 0) - System.out.println(indentation + threads.get(i)); - i = groups.size(); - while (--i >= 0) - ((ThreadGroup) groups.get(i)).list(indentation); - } - - /** - * Add a thread to the group. Called by Thread constructors. - * - * @param t the thread to add, non-null - * @throws IllegalThreadStateException if the group is destroyed - */ - final synchronized void addThread(Thread t) - { - if (groups == null) - throw new IllegalThreadStateException("ThreadGroup is destroyed"); - threads.add(t); - } - - /** - * Called by the VM to remove a thread that has died. - * - * @param t the thread to remove, non-null - * @XXX A ThreadListener to call this might be nice. - */ - final synchronized void removeThread(Thread t) - { - if (groups == null) - return; - threads.remove(t); - t.group = null; - // Daemon groups are automatically destroyed when all their threads die. - if (daemon_flag && groups.size() == 0 && threads.size() == 0) - { - // We inline destroy to avoid the access check. - groups = null; - if (parent != null) - parent.removeGroup(this); - } - } - - /** - * Called when a group is destroyed, to remove it from its parent. - * - * @param g the destroyed group, non-null - */ - final synchronized void removeGroup(ThreadGroup g) - { - groups.remove(g); - // Daemon groups are automatically destroyed when all their threads die. - if (daemon_flag && groups.size() == 0 && threads.size() == 0) - { - // We inline destroy to avoid the access check. - groups = null; - if (parent != null) - parent.removeGroup(this); - } - } -} // class ThreadGroup |