📄 threadgroup.java
字号:
* 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 exception the uncaught exception * @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.print(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); // 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -