Thread.java

来源:互联网 发布:java入门到精通 4 pdf 编辑:程序博客网 时间:2024/06/05 06:34
/* * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */package java.lang;import java.lang.ref.Reference;import java.lang.ref.ReferenceQueue;import java.lang.ref.WeakReference;import java.security.AccessController;import java.security.AccessControlContext;import java.security.PrivilegedAction;import java.util.Map;import java.util.HashMap;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentMap;import java.util.concurrent.locks.LockSupport;import sun.nio.ch.Interruptible;import sun.reflect.CallerSensitive;import sun.reflect.Reflection;import sun.security.util.SecurityConstants;/** * A <i>thread</i> is a thread of execution in a program. The Java * Virtual Machine allows an application to have multiple threads of * execution running concurrently. * <p> * Every thread has a priority. Threads with higher priority are * executed in preference to threads with lower priority. Each thread * may or may not also be marked as a daemon. When code running in * some thread creates a new <code>Thread</code> object, the new * thread has its priority initially set equal to the priority of the * creating thread, and is a daemon thread if and only if the * creating thread is a daemon. * <p> * When a Java Virtual Machine starts up, there is usually a single * non-daemon thread (which typically calls the method named * <code>main</code> of some designated class). The Java Virtual * Machine continues to execute threads until either of the following * occurs: * <ul> * <li>The <code>exit</code> method of class <code>Runtime</code> has been *     called and the security manager has permitted the exit operation *     to take place. * <li>All threads that are not daemon threads have died, either by *     returning from the call to the <code>run</code> method or by *     throwing an exception that propagates beyond the <code>run</code> *     method. * </ul> * <p> * There are two ways to create a new thread of execution. One is to * declare a class to be a subclass of <code>Thread</code>. This * subclass should override the <code>run</code> method of class * <code>Thread</code>. An instance of the subclass can then be * allocated and started. For example, a thread that computes primes * larger than a stated value could be written as follows: * <p><hr><blockquote><pre> *     class PrimeThread extends Thread { *         long minPrime; *         PrimeThread(long minPrime) { *             this.minPrime = minPrime; *         } * *         public void run() { *             // compute primes larger than minPrime *              . . . *         } *     } * </pre></blockquote><hr> * <p> * The following code would then create a thread and start it running: * <p><blockquote><pre> *     PrimeThread p = new PrimeThread(143); *     p.start(); * </pre></blockquote> * <p> * The other way to create a thread is to declare a class that * implements the <code>Runnable</code> interface. That class then * implements the <code>run</code> method. An instance of the class can * then be allocated, passed as an argument when creating * <code>Thread</code>, and started. The same example in this other * style looks like the following: * <p><hr><blockquote><pre> *     class PrimeRun implements Runnable { *         long minPrime; *         PrimeRun(long minPrime) { *             this.minPrime = minPrime; *         } * *         public void run() { *             // compute primes larger than minPrime *              . . . *         } *     } * </pre></blockquote><hr> * <p> * The following code would then create a thread and start it running: * <p><blockquote><pre> *     PrimeRun p = new PrimeRun(143); *     new Thread(p).start(); * </pre></blockquote> * <p> * Every thread has a name for identification purposes. More than * one thread may have the same name. If a name is not specified when * a thread is created, a new name is generated for it. * <p> * Unless otherwise noted, passing a {@code null} argument to a constructor * or method in this class will cause a {@link NullPointerException} to be * thrown. * * @author  unascribed * @see     Runnable * @see     Runtime#exit(int) * @see     #run() * @see     #stop() * @since   JDK1.0 */publicclass Thread implements Runnable {    /* Make sure registerNatives is the first thing <clinit> does. */    private static native void registerNatives();    static {        registerNatives();    }    private char        name[];    private int         priority;    private Thread      threadQ;    private long        eetop;    /* Whether or not to single_step this thread. */    private boolean     single_step;    /* Whether or not the thread is a daemon thread. */    private boolean     daemon = false;    /* JVM state */    private boolean     stillborn = false;    /* What will be run. */    private Runnable target;    /* The group of this thread */    private ThreadGroup group;    /* The context ClassLoader for this thread */    private ClassLoader contextClassLoader;    /* The inherited AccessControlContext of this thread */    private AccessControlContext inheritedAccessControlContext;    /* For autonumbering anonymous threads. */    private static int threadInitNumber;    private static synchronized int nextThreadNum() {        return threadInitNumber++;    }    /* ThreadLocal values pertaining to this thread. This map is maintained     * by the ThreadLocal class. */    ThreadLocal.ThreadLocalMap threadLocals = null;    /*     * InheritableThreadLocal values pertaining to this thread. This map is     * maintained by the InheritableThreadLocal class.     */    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;    /*     * The requested stack size for this thread, or 0 if the creator did     * not specify a stack size.  It is up to the VM to do whatever it     * likes with this number; some VMs will ignore it.     */    private long stackSize;    /*     * JVM-private state that persists after native thread termination.     */    private long nativeParkEventPointer;    /*     * Thread ID     */    private long tid;    /* For generating thread ID */    private static long threadSeqNumber;    /* Java thread status for tools,     * initialized to indicate thread 'not yet started'     */    private volatile int threadStatus = 0;    private static synchronized long nextThreadID() {        return ++threadSeqNumber;    }    /**     * The argument supplied to the current call to     * java.util.concurrent.locks.LockSupport.park.     * Set by (private) java.util.concurrent.locks.LockSupport.setBlocker     * Accessed using java.util.concurrent.locks.LockSupport.getBlocker     */    volatile Object parkBlocker;    /* The object in which this thread is blocked in an interruptible I/O     * operation, if any.  The blocker's interrupt method should be invoked     * after setting this thread's interrupt status.     */    private volatile Interruptible blocker;    private final Object blockerLock = new Object();    /* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code     */    void blockedOn(Interruptible b) {        synchronized (blockerLock) {            blocker = b;        }    }    /**     * The minimum priority that a thread can have.     */    public final static int MIN_PRIORITY = 1;   /**     * The default priority that is assigned to a thread.     */    public final static int NORM_PRIORITY = 5;    /**     * The maximum priority that a thread can have.     */    public final static int MAX_PRIORITY = 10;    /**     * Returns a reference to the currently executing thread object.     *     * @return  the currently executing thread.     */    public static native Thread currentThread();    /**     * A hint to the scheduler that the current thread is willing to yield     * its current use of a processor. The scheduler is free to ignore this     * hint.     *     * <p> Yield is a heuristic attempt to improve relative progression     * between threads that would otherwise over-utilise a CPU. Its use     * should be combined with detailed profiling and benchmarking to     * ensure that it actually has the desired effect.     *     * <p> It is rarely appropriate to use this method. It may be useful     * for debugging or testing purposes, where it may help to reproduce     * bugs due to race conditions. It may also be useful when designing     * concurrency control constructs such as the ones in the     * {@link java.util.concurrent.locks} package.     */    public static native void yield();    /**     * Causes the currently executing thread to sleep (temporarily cease     * execution) for the specified number of milliseconds, subject to     * the precision and accuracy of system timers and schedulers. The thread     * does not lose ownership of any monitors.     *     * @param  millis     *         the length of time to sleep in milliseconds     *     * @throws  IllegalArgumentException     *          if the value of {@code millis} is negative     *     * @throws  InterruptedException     *          if any thread has interrupted the current thread. The     *          <i>interrupted status</i> of the current thread is     *          cleared when this exception is thrown.     */    public static native void sleep(long millis) throws InterruptedException;    /**     * Causes the currently executing thread to sleep (temporarily cease     * execution) for the specified number of milliseconds plus the specified     * number of nanoseconds, subject to the precision and accuracy of system     * timers and schedulers. The thread does not lose ownership of any     * monitors.     *     * @param  millis     *         the length of time to sleep in milliseconds     *     * @param  nanos     *         {@code 0-999999} additional nanoseconds to sleep     *     * @throws  IllegalArgumentException     *          if the value of {@code millis} is negative, or the value of     *          {@code nanos} is not in the range {@code 0-999999}     *     * @throws  InterruptedException     *          if any thread has interrupted the current thread. The     *          <i>interrupted status</i> of the current thread is     *          cleared when this exception is thrown.     */    public static void sleep(long millis, int nanos)    throws InterruptedException {        if (millis < 0) {            throw new IllegalArgumentException("timeout value is negative");        }        if (nanos < 0 || nanos > 999999) {            throw new IllegalArgumentException(                                "nanosecond timeout value out of range");        }        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {            millis++;        }        sleep(millis);    }    /**     * Initializes a Thread with the current AccessControlContext.     * @see #init(ThreadGroup,Runnable,String,long,AccessControlContext)     */    private void init(ThreadGroup g, Runnable target, String name,                      long stackSize) {        init(g, target, name, stackSize, null);    }    /**     * Initializes a Thread.     *     * @param g the Thread group     * @param target the object whose run() method gets called     * @param name the name of the new Thread     * @param stackSize the desired stack size for the new thread, or     *        zero to indicate that this parameter is to be ignored.     * @param acc the AccessControlContext to inherit, or     *            AccessController.getContext() if null     */    private void init(ThreadGroup g, Runnable target, String name,                      long stackSize, AccessControlContext acc) {        if (name == null) {            throw new NullPointerException("name cannot be null");        }        this.name = name.toCharArray();        Thread parent = currentThread();        SecurityManager security = System.getSecurityManager();        if (g == null) {            /* Determine if it's an applet or not */            /* If there is a security manager, ask the security manager               what to do. */            if (security != null) {                g = security.getThreadGroup();            }            /* If the security doesn't have a strong opinion of the matter               use the parent thread group. */            if (g == null) {                g = parent.getThreadGroup();            }        }        /* checkAccess regardless of whether or not threadgroup is           explicitly passed in. */        g.checkAccess();        /*         * Do we have the required permissions?         */        if (security != null) {            if (isCCLOverridden(getClass())) {                security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);            }        }        g.addUnstarted();        this.group = g;        this.daemon = parent.isDaemon();        this.priority = parent.getPriority();        if (security == null || isCCLOverridden(parent.getClass()))            this.contextClassLoader = parent.getContextClassLoader();        else            this.contextClassLoader = parent.contextClassLoader;        this.inheritedAccessControlContext =                acc != null ? acc : AccessController.getContext();        this.target = target;        setPriority(priority);        if (parent.inheritableThreadLocals != null)            this.inheritableThreadLocals =                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);        /* Stash the specified stack size in case the VM cares */        this.stackSize = stackSize;        /* Set thread ID */        tid = nextThreadID();    }    /**     * Throws CloneNotSupportedException as a Thread can not be meaningfully     * cloned. Construct a new Thread instead.     *     * @throws  CloneNotSupportedException     *          always     */    @Override    protected Object clone() throws CloneNotSupportedException {        throw new CloneNotSupportedException();    }    /**     * Allocates a new {@code Thread} object. This constructor has the same     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}     * {@code (null, null, gname)}, where {@code gname} is a newly generated     * name. Automatically generated names are of the form     * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.     */    public Thread() {        init(null, null, "Thread-" + nextThreadNum(), 0);    }    /**     * Allocates a new {@code Thread} object. This constructor has the same     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}     * {@code (null, target, gname)}, where {@code gname} is a newly generated     * name. Automatically generated names are of the form     * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.     *     * @param  target     *         the object whose {@code run} method is invoked when this thread     *         is started. If {@code null}, this classes {@code run} method does     *         nothing.     */    public Thread(Runnable target) {        init(null, target, "Thread-" + nextThreadNum(), 0);    }    /**     * Creates a new Thread that inherits the given AccessControlContext.     * This is not a public constructor.     */    Thread(Runnable target, AccessControlContext acc) {        init(null, target, "Thread-" + nextThreadNum(), 0, acc);    }    /**     * Allocates a new {@code Thread} object. This constructor has the same     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}     * {@code (group, target, gname)} ,where {@code gname} is a newly generated     * name. Automatically generated names are of the form     * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.     *     * @param  group     *         the thread group. If {@code null} and there is a security     *         manager, the group is determined by {@linkplain     *         SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.     *         If there is not a security manager or {@code     *         SecurityManager.getThreadGroup()} returns {@code null}, the group     *         is set to the current thread's thread group.     *     * @param  target     *         the object whose {@code run} method is invoked when this thread     *         is started. If {@code null}, this thread's run method is invoked.     *     * @throws  SecurityException     *          if the current thread cannot create a thread in the specified     *          thread group     */    public Thread(ThreadGroup group, Runnable target) {        init(group, target, "Thread-" + nextThreadNum(), 0);    }    /**     * Allocates a new {@code Thread} object. This constructor has the same     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}     * {@code (null, null, name)}.     *     * @param   name     *          the name of the new thread     */    public Thread(String name) {        init(null, null, name, 0);    }    /**     * Allocates a new {@code Thread} object. This constructor has the same     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}     * {@code (group, null, name)}.     *     * @param  group     *         the thread group. If {@code null} and there is a security     *         manager, the group is determined by {@linkplain     *         SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.     *         If there is not a security manager or {@code     *         SecurityManager.getThreadGroup()} returns {@code null}, the group     *         is set to the current thread's thread group.     *     * @param  name     *         the name of the new thread     *     * @throws  SecurityException     *          if the current thread cannot create a thread in the specified     *          thread group     */    public Thread(ThreadGroup group, String name) {        init(group, null, name, 0);    }    /**     * Allocates a new {@code Thread} object. This constructor has the same     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}     * {@code (null, target, name)}.     *     * @param  target     *         the object whose {@code run} method is invoked when this thread     *         is started. If {@code null}, this thread's run method is invoked.     *     * @param  name     *         the name of the new thread     */    public Thread(Runnable target, String name) {        init(null, target, name, 0);    }    /**     * Allocates a new {@code Thread} object so that it has {@code target}     * as its run object, has the specified {@code name} as its name,     * and belongs to the thread group referred to by {@code group}.     *     * <p>If there is a security manager, its     * {@link SecurityManager#checkAccess(ThreadGroup) checkAccess}     * method is invoked with the ThreadGroup as its argument.     *     * <p>In addition, its {@code checkPermission} method is invoked with     * the {@code RuntimePermission("enableContextClassLoaderOverride")}     * permission when invoked directly or indirectly by the constructor     * of a subclass which overrides the {@code getContextClassLoader}     * or {@code setContextClassLoader} methods.     *     * <p>The priority of the newly created thread is set equal to the     * priority of the thread creating it, that is, the currently running     * thread. The method {@linkplain #setPriority setPriority} may be     * used to change the priority to a new value.     *     * <p>The newly created thread is initially marked as being a daemon     * thread if and only if the thread creating it is currently marked     * as a daemon thread. The method {@linkplain #setDaemon setDaemon}     * may be used to change whether or not a thread is a daemon.     *     * @param  group     *         the thread group. If {@code null} and there is a security     *         manager, the group is determined by {@linkplain     *         SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.     *         If there is not a security manager or {@code     *         SecurityManager.getThreadGroup()} returns {@code null}, the group     *         is set to the current thread's thread group.     *     * @param  target     *         the object whose {@code run} method is invoked when this thread     *         is started. If {@code null}, this thread's run method is invoked.     *     * @param  name     *         the name of the new thread     *     * @throws  SecurityException     *          if the current thread cannot create a thread in the specified     *          thread group or cannot override the context class loader methods.     */    public Thread(ThreadGroup group, Runnable target, String name) {        init(group, target, name, 0);    }    /**     * Allocates a new {@code Thread} object so that it has {@code target}     * as its run object, has the specified {@code name} as its name,     * and belongs to the thread group referred to by {@code group}, and has     * the specified <i>stack size</i>.     *     * <p>This constructor is identical to {@link     * #Thread(ThreadGroup,Runnable,String)} with the exception of the fact     * that it allows the thread stack size to be specified.  The stack size     * is the approximate number of bytes of address space that the virtual     * machine is to allocate for this thread's stack.  <b>The effect of the     * {@code stackSize} parameter, if any, is highly platform dependent.</b>     *     * <p>On some platforms, specifying a higher value for the     * {@code stackSize} parameter may allow a thread to achieve greater     * recursion depth before throwing a {@link StackOverflowError}.     * Similarly, specifying a lower value may allow a greater number of     * threads to exist concurrently without throwing an {@link     * OutOfMemoryError} (or other internal error).  The details of     * the relationship between the value of the <tt>stackSize</tt> parameter     * and the maximum recursion depth and concurrency level are     * platform-dependent.  <b>On some platforms, the value of the     * {@code stackSize} parameter may have no effect whatsoever.</b>     *     * <p>The virtual machine is free to treat the {@code stackSize}     * parameter as a suggestion.  If the specified value is unreasonably low     * for the platform, the virtual machine may instead use some     * platform-specific minimum value; if the specified value is unreasonably     * high, the virtual machine may instead use some platform-specific     * maximum.  Likewise, the virtual machine is free to round the specified     * value up or down as it sees fit (or to ignore it completely).     *     * <p>Specifying a value of zero for the {@code stackSize} parameter will     * cause this constructor to behave exactly like the     * {@code Thread(ThreadGroup, Runnable, String)} constructor.     *     * <p><i>Due to the platform-dependent nature of the behavior of this     * constructor, extreme care should be exercised in its use.     * The thread stack size necessary to perform a given computation will     * likely vary from one JRE implementation to another.  In light of this     * variation, careful tuning of the stack size parameter may be required,     * and the tuning may need to be repeated for each JRE implementation on     * which an application is to run.</i>     *     * <p>Implementation note: Java platform implementers are encouraged to     * document their implementation's behavior with respect to the     * {@code stackSize} parameter.     *     *     * @param  group     *         the thread group. If {@code null} and there is a security     *         manager, the group is determined by {@linkplain     *         SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.     *         If there is not a security manager or {@code     *         SecurityManager.getThreadGroup()} returns {@code null}, the group     *         is set to the current thread's thread group.     *     * @param  target     *         the object whose {@code run} method is invoked when this thread     *         is started. If {@code null}, this thread's run method is invoked.     *     * @param  name     *         the name of the new thread     *     * @param  stackSize     *         the desired stack size for the new thread, or zero to indicate     *         that this parameter is to be ignored.     *     * @throws  SecurityException     *          if the current thread cannot create a thread in the specified     *          thread group     *     * @since 1.4     */    public Thread(ThreadGroup group, Runnable target, String name,                  long stackSize) {        init(group, target, name, stackSize);    }    /**     * Causes this thread to begin execution; the Java Virtual Machine     * calls the <code>run</code> method of this thread.     * <p>     * The result is that two threads are running concurrently: the     * current thread (which returns from the call to the     * <code>start</code> method) and the other thread (which executes its     * <code>run</code> method).     * <p>     * It is never legal to start a thread more than once.     * In particular, a thread may not be restarted once it has completed     * execution.     *     * @exception  IllegalThreadStateException  if the thread was already     *               started.     * @see        #run()     * @see        #stop()     */    public synchronized void start() {        /**         * This method is not invoked for the main method thread or "system"         * group threads created/set up by the VM. Any new functionality added         * to this method in the future may have to also be added to the VM.         *         * A zero status value corresponds to state "NEW".         */        if (threadStatus != 0)            throw new IllegalThreadStateException();        /* Notify the group that this thread is about to be started         * so that it can be added to the group's list of threads         * and the group's unstarted count can be decremented. */        group.add(this);        boolean started = false;        try {            start0();            started = true;        } finally {            try {                if (!started) {                    group.threadStartFailed(this);                }            } catch (Throwable ignore) {                /* do nothing. If start0 threw a Throwable then                  it will be passed up the call stack */            }        }    }    private native void start0();    /**     * If this thread was constructed using a separate     * <code>Runnable</code> run object, then that     * <code>Runnable</code> object's <code>run</code> method is called;     * otherwise, this method does nothing and returns.     * <p>     * Subclasses of <code>Thread</code> should override this method.     *     * @see     #start()     * @see     #stop()     * @see     #Thread(ThreadGroup, Runnable, String)     */    @Override    public void run() {        if (target != null) {            target.run();        }    }    /**     * This method is called by the system to give a Thread     * a chance to clean up before it actually exits.     */    private void exit() {        if (group != null) {            group.threadTerminated(this);            group = null;        }        /* Aggressively null out all reference fields: see bug 4006245 */        target = null;        /* Speed the release of some of these resources */        threadLocals = null;        inheritableThreadLocals = null;        inheritedAccessControlContext = null;        blocker = null;        uncaughtExceptionHandler = null;    }    /**     * Forces the thread to stop executing.     * <p>     * If there is a security manager installed, its <code>checkAccess</code>     * method is called with <code>this</code>     * as its argument. This may result in a     * <code>SecurityException</code> being raised (in the current thread).     * <p>     * If this thread is different from the current thread (that is, the current     * thread is trying to stop a thread other than itself), the     * security manager's <code>checkPermission</code> method (with a     * <code>RuntimePermission("stopThread")</code> argument) is called in     * addition.     * Again, this may result in throwing a     * <code>SecurityException</code> (in the current thread).     * <p>     * The thread represented by this thread is forced to stop whatever     * it is doing abnormally and to throw a newly created     * <code>ThreadDeath</code> object as an exception.     * <p>     * It is permitted to stop a thread that has not yet been started.     * If the thread is eventually started, it immediately terminates.     * <p>     * An application should not normally try to catch     * <code>ThreadDeath</code> unless it must do some extraordinary     * cleanup operation (note that the throwing of     * <code>ThreadDeath</code> causes <code>finally</code> clauses of     * <code>try</code> statements to be executed before the thread     * officially dies).  If a <code>catch</code> clause catches a     * <code>ThreadDeath</code> object, it is important to rethrow the     * object so that the thread actually dies.     * <p>     * The top-level error handler that reacts to otherwise uncaught     * exceptions does not print out a message or otherwise notify the     * application if the uncaught exception is an instance of     * <code>ThreadDeath</code>.     *     * @exception  SecurityException  if the current thread cannot     *               modify this thread.     * @see        #interrupt()     * @see        #checkAccess()     * @see        #run()     * @see        #start()     * @see        ThreadDeath     * @see        ThreadGroup#uncaughtException(Thread,Throwable)     * @see        SecurityManager#checkAccess(Thread)     * @see        SecurityManager#checkPermission     * @deprecated This method is inherently unsafe.  Stopping a thread with     *       Thread.stop causes it to unlock all of the monitors that it     *       has locked (as a natural consequence of the unchecked     *       <code>ThreadDeath</code> exception propagating up the stack).  If     *       any of the objects previously protected by these monitors were in     *       an inconsistent state, the damaged objects become visible to     *       other threads, potentially resulting in arbitrary behavior.  Many     *       uses of <code>stop</code> should be replaced by code that simply     *       modifies some variable to indicate that the target thread should     *       stop running.  The target thread should check this variable     *       regularly, and return from its run method in an orderly fashion     *       if the variable indicates that it is to stop running.  If the     *       target thread waits for long periods (on a condition variable,     *       for example), the <code>interrupt</code> method should be used to     *       interrupt the wait.     *       For more information, see     *       <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why     *       are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.     */    @Deprecated    public final void stop() {        stop(new ThreadDeath());    }    /**     * Forces the thread to stop executing.     * <p>     * If there is a security manager installed, the <code>checkAccess</code>     * method of this thread is called, which may result in a     * <code>SecurityException</code> being raised (in the current thread).     * <p>     * If this thread is different from the current thread (that is, the current     * thread is trying to stop a thread other than itself) or     * <code>obj</code> is not an instance of <code>ThreadDeath</code>, the     * security manager's <code>checkPermission</code> method (with the     * <code>RuntimePermission("stopThread")</code> argument) is called in     * addition.     * Again, this may result in throwing a     * <code>SecurityException</code> (in the current thread).     * <p>     * If the argument <code>obj</code> is null, a     * <code>NullPointerException</code> is thrown (in the current thread).     * <p>     * The thread represented by this thread is forced to stop     * whatever it is doing abnormally and to throw the     * <code>Throwable</code> object <code>obj</code> as an exception. This     * is an unusual action to take; normally, the <code>stop</code> method     * that takes no arguments should be used.     * <p>     * It is permitted to stop a thread that has not yet been started.     * If the thread is eventually started, it immediately terminates.     *     * @param      obj   the Throwable object to be thrown.     * @exception  SecurityException  if the current thread cannot modify     *               this thread.     * @throws     NullPointerException if obj is <tt>null</tt>.     * @see        #interrupt()     * @see        #checkAccess()     * @see        #run()     * @see        #start()     * @see        #stop()     * @see        SecurityManager#checkAccess(Thread)     * @see        SecurityManager#checkPermission     * @deprecated This method is inherently unsafe.  See {@link #stop()}     *        for details.  An additional danger of this     *        method is that it may be used to generate exceptions that the     *        target thread is unprepared to handle (including checked     *        exceptions that the thread could not possibly throw, were it     *        not for this method).     *        For more information, see     *        <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why     *        are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.     */    @Deprecated    public final synchronized void stop(Throwable obj) {        if (obj == null)            throw new NullPointerException();        SecurityManager security = System.getSecurityManager();        if (security != null) {            checkAccess();            if ((this != Thread.currentThread()) ||                (!(obj instanceof ThreadDeath))) {                security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);            }        }        // A zero status value corresponds to "NEW", it can't change to        // not-NEW because we hold the lock.        if (threadStatus != 0) {            resume(); // Wake up thread if it was suspended; no-op otherwise        }        // The VM can handle all thread states        stop0(obj);    }    /**     * Interrupts this thread.     *     * <p> Unless the current thread is interrupting itself, which is     * always permitted, the {@link #checkAccess() checkAccess} method     * of this thread is invoked, which may cause a {@link     * SecurityException} to be thrown.     *     * <p> If this thread is blocked in an invocation of the {@link     * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link     * Object#wait(long, int) wait(long, int)} methods of the {@link Object}     * class, or of the {@link #join()}, {@link #join(long)}, {@link     * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)},     * methods of this class, then its interrupt status will be cleared and it     * will receive an {@link InterruptedException}.     *     * <p> If this thread is blocked in an I/O operation upon an {@link     * java.nio.channels.InterruptibleChannel </code>interruptible     * channel<code>} then the channel will be closed, the thread's interrupt     * status will be set, and the thread will receive a {@link     * java.nio.channels.ClosedByInterruptException}.     *     * <p> If this thread is blocked in a {@link java.nio.channels.Selector}     * then the thread's interrupt status will be set and it will return     * immediately from the selection operation, possibly with a non-zero     * value, just as if the selector's {@link     * java.nio.channels.Selector#wakeup wakeup} method were invoked.     *     * <p> If none of the previous conditions hold then this thread's interrupt     * status will be set. </p>     *     * <p> Interrupting a thread that is not alive need not have any effect.     *     * @throws  SecurityException     *          if the current thread cannot modify this thread     *     * @revised 6.0     * @spec JSR-51     */    public void interrupt() {        if (this != Thread.currentThread())            checkAccess();        synchronized (blockerLock) {            Interruptible b = blocker;            if (b != null) {                interrupt0();           // Just to set the interrupt flag                b.interrupt(this);                return;            }        }        interrupt0();    }    /**     * Tests whether the current thread has been interrupted.  The     * <i>interrupted status</i> of the thread is cleared by this method.  In     * other words, if this method were to be called twice in succession, the     * second call would return false (unless the current thread were     * interrupted again, after the first call had cleared its interrupted     * status and before the second call had examined it).     *     * <p>A thread interruption ignored because a thread was not alive     * at the time of the interrupt will be reflected by this method     * returning false.     *     * @return  <code>true</code> if the current thread has been interrupted;     *          <code>false</code> otherwise.     * @see #isInterrupted()     * @revised 6.0     */    public static boolean interrupted() {        return currentThread().isInterrupted(true);    }    /**     * Tests whether this thread has been interrupted.  The <i>interrupted     * status</i> of the thread is unaffected by this method.     *     * <p>A thread interruption ignored because a thread was not alive     * at the time of the interrupt will be reflected by this method     * returning false.     *     * @return  <code>true</code> if this thread has been interrupted;     *          <code>false</code> otherwise.     * @see     #interrupted()     * @revised 6.0     */    public boolean isInterrupted() {        return isInterrupted(false);    }    /**     * Tests if some Thread has been interrupted.  The interrupted state     * is reset or not based on the value of ClearInterrupted that is     * passed.     */    private native boolean isInterrupted(boolean ClearInterrupted);    /**     * Throws {@link NoSuchMethodError}.     *     * @deprecated This method was originally designed to destroy this     *     thread without any cleanup. Any monitors it held would have     *     remained locked. However, the method was never implemented.     *     If if were to be implemented, it would be deadlock-prone in     *     much the manner of {@link #suspend}. If the target thread held     *     a lock protecting a critical system resource when it was     *     destroyed, no thread could ever access this resource again.     *     If another thread ever attempted to lock this resource, deadlock     *     would result. Such deadlocks typically manifest themselves as     *     "frozen" processes. For more information, see     *     <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">     *     Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.     * @throws NoSuchMethodError always     */    @Deprecated    public void destroy() {        throw new NoSuchMethodError();    }    /**     * Tests if this thread is alive. A thread is alive if it has     * been started and has not yet died.     *     * @return  <code>true</code> if this thread is alive;     *          <code>false</code> otherwise.     */    public final native boolean isAlive();    /**     * Suspends this thread.     * <p>     * First, the <code>checkAccess</code> method of this thread is called     * with no arguments. This may result in throwing a     * <code>SecurityException </code>(in the current thread).     * <p>     * If the thread is alive, it is suspended and makes no further     * progress unless and until it is resumed.     *     * @exception  SecurityException  if the current thread cannot modify     *               this thread.     * @see #checkAccess     * @deprecated   This method has been deprecated, as it is     *   inherently deadlock-prone.  If the target thread holds a lock on the     *   monitor protecting a critical system resource when it is suspended, no     *   thread can access this resource until the target thread is resumed. If     *   the thread that would resume the target thread attempts to lock this     *   monitor prior to calling <code>resume</code>, deadlock results.  Such     *   deadlocks typically manifest themselves as "frozen" processes.     *   For more information, see     *   <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why     *   are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.     */    @Deprecated    public final void suspend() {        checkAccess();        suspend0();    }    /**     * Resumes a suspended thread.     * <p>     * First, the <code>checkAccess</code> method of this thread is called     * with no arguments. This may result in throwing a     * <code>SecurityException</code> (in the current thread).     * <p>     * If the thread is alive but suspended, it is resumed and is     * permitted to make progress in its execution.     *     * @exception  SecurityException  if the current thread cannot modify this     *               thread.     * @see        #checkAccess     * @see        #suspend()     * @deprecated This method exists solely for use with {@link #suspend},     *     which has been deprecated because it is deadlock-prone.     *     For more information, see     *     <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why     *     are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.     */    @Deprecated    public final void resume() {        checkAccess();        resume0();    }    /**     * Changes the priority of this thread.     * <p>     * First the <code>checkAccess</code> method of this thread is called     * with no arguments. This may result in throwing a     * <code>SecurityException</code>.     * <p>     * Otherwise, the priority of this thread is set to the smaller of     * the specified <code>newPriority</code> and the maximum permitted     * priority of the thread's thread group.     *     * @param newPriority priority to set this thread to     * @exception  IllegalArgumentException  If the priority is not in the     *               range <code>MIN_PRIORITY</code> to     *               <code>MAX_PRIORITY</code>.     * @exception  SecurityException  if the current thread cannot modify     *               this thread.     * @see        #getPriority     * @see        #checkAccess()     * @see        #getThreadGroup()     * @see        #MAX_PRIORITY     * @see        #MIN_PRIORITY     * @see        ThreadGroup#getMaxPriority()     */    public final void setPriority(int newPriority) {        ThreadGroup g;        checkAccess();        if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {            throw new IllegalArgumentException();        }        if((g = getThreadGroup()) != null) {            if (newPriority > g.getMaxPriority()) {                newPriority = g.getMaxPriority();            }            setPriority0(priority = newPriority);        }    }    /**     * Returns this thread's priority.     *     * @return  this thread's priority.     * @see     #setPriority     */    public final int getPriority() {        return priority;    }    /**     * Changes the name of this thread to be equal to the argument     * <code>name</code>.     * <p>     * First the <code>checkAccess</code> method of this thread is called     * with no arguments. This may result in throwing a     * <code>SecurityException</code>.     *     * @param      name   the new name for this thread.     * @exception  SecurityException  if the current thread cannot modify this     *               thread.     * @see        #getName     * @see        #checkAccess()     */    public final void setName(String name) {        checkAccess();        this.name = name.toCharArray();    }    /**     * Returns this thread's name.     *     * @return  this thread's name.     * @see     #setName(String)     */    public final String getName() {        return String.valueOf(name);    }    /**     * Returns the thread group to which this thread belongs.     * This method returns null if this thread has died     * (been stopped).     *     * @return  this thread's thread group.     */    public final ThreadGroup getThreadGroup() {        return group;    }    /**     * Returns an estimate of the number of active threads in the current     * thread's {@linkplain java.lang.ThreadGroup thread group} and its     * subgroups. Recursively iterates over all subgroups in the current     * thread's thread group.     *     * <p> The value returned is only an estimate because the number of     * threads may change dynamically while this method traverses internal     * data structures, and might be affected by the presence of certain     * system threads. This method is intended primarily for debugging     * and monitoring purposes.     *     * @return  an estimate of the number of active threads in the current     *          thread's thread group and in any other thread group that     *          has the current thread's thread group as an ancestor     */    public static int activeCount() {        return currentThread().getThreadGroup().activeCount();    }    /**     * Copies into the specified array every active thread in the current     * thread's thread group and its subgroups. This method simply     * invokes the {@link java.lang.ThreadGroup#enumerate(Thread[])}     * method of the current thread's thread group.     *     * <p> An application might use the {@linkplain #activeCount activeCount}     * method to get an estimate of how big the array should be, however     * <i>if the array is too short to hold all the threads, the extra threads     * are silently ignored.</i>  If it is critical to obtain every active     * thread in the current thread's thread group and its subgroups, the     * invoker should verify that the returned int value is strictly less     * than the length of {@code tarray}.     *     * <p> Due to the inherent race condition in this method, it is recommended     * that the method only be used for debugging and monitoring purposes.     *     * @param  tarray     *         an array into which to put the list of threads     *     * @return  the number of threads put into the array     *     * @throws  SecurityException     *          if {@link java.lang.ThreadGroup#checkAccess} determines that     *          the current thread cannot access its thread group     */    public static int enumerate(Thread tarray[]) {        return currentThread().getThreadGroup().enumerate(tarray);    }    /**     * Counts the number of stack frames in this thread. The thread must     * be suspended.     *     * @return     the number of stack frames in this thread.     * @exception  IllegalThreadStateException  if this thread is not     *             suspended.     * @deprecated The definition of this call depends on {@link #suspend},     *             which is deprecated.  Further, the results of this call     *             were never well-defined.     */    @Deprecated    public native int countStackFrames();    /**     * Waits at most {@code millis} milliseconds for this thread to     * die. A timeout of {@code 0} means to wait forever.     *     * <p> This implementation uses a loop of {@code this.wait} calls     * conditioned on {@code this.isAlive}. As a thread terminates the     * {@code this.notifyAll} method is invoked. It is recommended that     * applications not use {@code wait}, {@code notify}, or     * {@code notifyAll} on {@code Thread} instances.     *     * @param  millis     *         the time to wait in milliseconds     *     * @throws  IllegalArgumentException     *          if the value of {@code millis} is negative     *     * @throws  InterruptedException     *          if any thread has interrupted the current thread. The     *          <i>interrupted status</i> of the current thread is     *          cleared when this exception is thrown.     */    public final synchronized void join(long millis)    throws InterruptedException {        long base = System.currentTimeMillis();        long now = 0;        if (millis < 0) {            throw new IllegalArgumentException("timeout value is negative");        }        if (millis == 0) {            while (isAlive()) {                wait(0);            }        } else {            while (isAlive()) {                long delay = millis - now;                if (delay <= 0) {                    break;                }                wait(delay);                now = System.currentTimeMillis() - base;            }        }    }    /**     * Waits at most {@code millis} milliseconds plus     * {@code nanos} nanoseconds for this thread to die.     *     * <p> This implementation uses a loop of {@code this.wait} calls     * conditioned on {@code this.isAlive}. As a thread terminates the     * {@code this.notifyAll} method is invoked. It is recommended that     * applications not use {@code wait}, {@code notify}, or     * {@code notifyAll} on {@code Thread} instances.     *     * @param  millis     *         the time to wait in milliseconds     *     * @param  nanos     *         {@code 0-999999} additional nanoseconds to wait     *     * @throws  IllegalArgumentException     *          if the value of {@code millis} is negative, or the value     *          of {@code nanos} is not in the range {@code 0-999999}     *     * @throws  InterruptedException     *          if any thread has interrupted the current thread. The     *          <i>interrupted status</i> of the current thread is     *          cleared when this exception is thrown.     */    public final synchronized void join(long millis, int nanos)    throws InterruptedException {        if (millis < 0) {            throw new IllegalArgumentException("timeout value is negative");        }        if (nanos < 0 || nanos > 999999) {            throw new IllegalArgumentException(                                "nanosecond timeout value out of range");        }        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {            millis++;        }        join(millis);    }    /**     * Waits for this thread to die.     *     * <p> An invocation of this method behaves in exactly the same     * way as the invocation     *     * <blockquote>     * {@linkplain #join(long) join}{@code (0)}     * </blockquote>     *     * @throws  InterruptedException     *          if any thread has interrupted the current thread. The     *          <i>interrupted status</i> of the current thread is     *          cleared when this exception is thrown.     */    public final void join() throws InterruptedException {        join(0);    }    /**     * Prints a stack trace of the current thread to the standard error stream.     * This method is used only for debugging.     *     * @see     Throwable#printStackTrace()     */    public static void dumpStack() {        new Exception("Stack trace").printStackTrace();    }    /**     * Marks this thread as either a {@linkplain #isDaemon daemon} thread     * or a user thread. The Java Virtual Machine exits when the only     * threads running are all daemon threads.     *     * <p> This method must be invoked before the thread is started.     *     * @param  on     *         if {@code true}, marks this thread as a daemon thread     *     * @throws  IllegalThreadStateException     *          if this thread is {@linkplain #isAlive alive}     *     * @throws  SecurityException     *          if {@link #checkAccess} determines that the current     *          thread cannot modify this thread     */    public final void setDaemon(boolean on) {        checkAccess();        if (isAlive()) {            throw new IllegalThreadStateException();        }        daemon = on;    }    /**     * Tests if this thread is a daemon thread.     *     * @return  <code>true</code> if this thread is a daemon thread;     *          <code>false</code> otherwise.     * @see     #setDaemon(boolean)     */    public final boolean isDaemon() {        return daemon;    }    /**     * Determines if the currently running thread has permission to     * modify this thread.     * <p>     * If there is a security manager, its <code>checkAccess</code> method     * is called with this thread as its argument. This may result in     * throwing a <code>SecurityException</code>.     *     * @exception  SecurityException  if the current thread is not allowed to     *               access this thread.     * @see        SecurityManager#checkAccess(Thread)     */    public final void checkAccess() {        SecurityManager security = System.getSecurityManager();        if (security != null) {            security.checkAccess(this);        }    }    /**     * Returns a string representation of this thread, including the     * thread's name, priority, and thread group.     *     * @return  a string representation of this thread.     */    public String toString() {        ThreadGroup group = getThreadGroup();        if (group != null) {            return "Thread[" + getName() + "," + getPriority() + "," +                           group.getName() + "]";        } else {            return "Thread[" + getName() + "," + getPriority() + "," +                            "" + "]";        }    }    /**     * Returns the context ClassLoader for this Thread. The context     * ClassLoader is provided by the creator of the thread for use     * by code running in this thread when loading classes and resources.     * If not {@linkplain #setContextClassLoader set}, the default is the     * ClassLoader context of the parent Thread. The context ClassLoader of the     * primordial thread is typically set to the class loader used to load the     * application.     *     * <p>If a security manager is present, and the invoker's class loader is not     * {@code null} and is not the same as or an ancestor of the context class     * loader, then this method invokes the security manager's {@link     * SecurityManager#checkPermission(java.security.Permission) checkPermission}     * method with a {@link RuntimePermission RuntimePermission}{@code     * ("getClassLoader")} permission to verify that retrieval of the context     * class loader is permitted.     *     * @return  the context ClassLoader for this Thread, or {@code null}     *          indicating the system class loader (or, failing that, the     *          bootstrap class loader)     *     * @throws  SecurityException     *          if the current thread cannot get the context ClassLoader     *     * @since 1.2     */    @CallerSensitive    public ClassLoader getContextClassLoader() {        if (contextClassLoader == null)            return null;        SecurityManager sm = System.getSecurityManager();        if (sm != null) {            ClassLoader.checkClassLoaderPermission(contextClassLoader,                                                   Reflection.getCallerClass());        }        return contextClassLoader;    }    /**     * Sets the context ClassLoader for this Thread. The context     * ClassLoader can be set when a thread is created, and allows     * the creator of the thread to provide the appropriate class loader,     * through {@code getContextClassLoader}, to code running in the thread     * when loading classes and resources.     *     * <p>If a security manager is present, its {@link     * SecurityManager#checkPermission(java.security.Permission) checkPermission}     * method is invoked with a {@link RuntimePermission RuntimePermission}{@code     * ("setContextClassLoader")} permission to see if setting the context     * ClassLoader is permitted.     *     * @param  cl     *         the context ClassLoader for this Thread, or null  indicating the     *         system class loader (or, failing that, the bootstrap class loader)     *     * @throws  SecurityException     *          if the current thread cannot set the context ClassLoader     *     * @since 1.2     */    public void setContextClassLoader(ClassLoader cl) {        SecurityManager sm = System.getSecurityManager();        if (sm != null) {            sm.checkPermission(new RuntimePermission("setContextClassLoader"));        }        contextClassLoader = cl;    }    /**     * Returns <tt>true</tt> if and only if the current thread holds the     * monitor lock on the specified object.     *     * <p>This method is designed to allow a program to assert that     * the current thread already holds a specified lock:     * <pre>     *     assert Thread.holdsLock(obj);     * </pre>     *     * @param  obj the object on which to test lock ownership     * @throws NullPointerException if obj is <tt>null</tt>     * @return <tt>true</tt> if the current thread holds the monitor lock on     *         the specified object.     * @since 1.4     */    public static native boolean holdsLock(Object obj);    private static final StackTraceElement[] EMPTY_STACK_TRACE        = new StackTraceElement[0];    /**     * Returns an array of stack trace elements representing the stack dump     * of this thread.  This method will return a zero-length array if     * this thread has not started, has started but has not yet been     * scheduled to run by the system, or has terminated.     * If the returned array is of non-zero length then the first element of     * the array represents the top of the stack, which is the most recent     * method invocation in the sequence.  The last element of the array     * represents the bottom of the stack, which is the least recent method     * invocation in the sequence.     *     * <p>If there is a security manager, and this thread is not     * the current thread, then the security manager's     * <tt>checkPermission</tt> method is called with a     * <tt>RuntimePermission("getStackTrace")</tt> permission     * to see if it's ok to get the stack trace.     *     * <p>Some virtual machines may, under some circumstances, omit one     * or more stack frames from the stack trace.  In the extreme case,     * a virtual machine that has no stack trace information concerning     * this thread is permitted to return a zero-length array from this     * method.     *     * @return an array of <tt>StackTraceElement</tt>,     * each represents one stack frame.     *     * @throws SecurityException     *        if a security manager exists and its     *        <tt>checkPermission</tt> method doesn't allow     *        getting the stack trace of thread.     * @see SecurityManager#checkPermission     * @see RuntimePermission     * @see Throwable#getStackTrace     *     * @since 1.5     */    public StackTraceElement[] getStackTrace() {        if (this != Thread.currentThread()) {            // check for getStackTrace permission            SecurityManager security = System.getSecurityManager();            if (security != null) {                security.checkPermission(                    SecurityConstants.GET_STACK_TRACE_PERMISSION);            }            // optimization so we do not call into the vm for threads that            // have not yet started or have terminated            if (!isAlive()) {                return EMPTY_STACK_TRACE;            }            StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this});            StackTraceElement[] stackTrace = stackTraceArray[0];            // a thread that was alive during the previous isAlive call may have            // since terminated, therefore not having a stacktrace.            if (stackTrace == null) {                stackTrace = EMPTY_STACK_TRACE;            }            return stackTrace;        } else {            // Don't need JVM help for current thread            return (new Exception()).getStackTrace();        }    }    /**     * Returns a map of stack traces for all live threads.     * The map keys are threads and each map value is an array of     * <tt>StackTraceElement</tt> that represents the stack dump     * of the corresponding <tt>Thread</tt>.     * The returned stack traces are in the format specified for     * the {@link #getStackTrace getStackTrace} method.     *     * <p>The threads may be executing while this method is called.     * The stack trace of each thread only represents a snapshot and     * each stack trace may be obtained at different time.  A zero-length     * array will be returned in the map value if the virtual machine has     * no stack trace information about a thread.     *     * <p>If there is a security manager, then the security manager's     * <tt>checkPermission</tt> method is called with a     * <tt>RuntimePermission("getStackTrace")</tt> permission as well as     * <tt>RuntimePermission("modifyThreadGroup")</tt> permission     * to see if it is ok to get the stack trace of all threads.     *     * @return a <tt>Map</tt> from <tt>Thread</tt> to an array of     * <tt>StackTraceElement</tt> that represents the stack trace of     * the corresponding thread.     *     * @throws SecurityException     *        if a security manager exists and its     *        <tt>checkPermission</tt> method doesn't allow     *        getting the stack trace of thread.     * @see #getStackTrace     * @see SecurityManager#checkPermission     * @see RuntimePermission     * @see Throwable#getStackTrace     *     * @since 1.5     */    public static Map<Thread, StackTraceElement[]> getAllStackTraces() {        // check for getStackTrace permission        SecurityManager security = System.getSecurityManager();        if (security != null) {            security.checkPermission(                SecurityConstants.GET_STACK_TRACE_PERMISSION);            security.checkPermission(                SecurityConstants.MODIFY_THREADGROUP_PERMISSION);        }        // Get a snapshot of the list of all threads        Thread[] threads = getThreads();        StackTraceElement[][] traces = dumpThreads(threads);        Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);        for (int i = 0; i < threads.length; i++) {            StackTraceElement[] stackTrace = traces[i];            if (stackTrace != null) {                m.put(threads[i], stackTrace);            }            // else terminated so we don't put it in the map        }        return m;    }    private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =                    new RuntimePermission("enableContextClassLoaderOverride");    /** cache of subclass security audit results */    /* Replace with ConcurrentReferenceHashMap when/if it appears in a future     * release */    private static class Caches {        /** cache of subclass security audit results */        static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =            new ConcurrentHashMap<>();        /** queue for WeakReferences to audited subclasses */        static final ReferenceQueue<Class<?>> subclassAuditsQueue =            new ReferenceQueue<>();    }    /**     * Verifies that this (possibly subclass) instance can be constructed     * without violating security constraints: the subclass must not override     * security-sensitive non-final methods, or else the     * "enableContextClassLoaderOverride" RuntimePermission is checked.     */    private static boolean isCCLOverridden(Class cl) {        if (cl == Thread.class)            return false;        processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);        WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);        Boolean result = Caches.subclassAudits.get(key);        if (result == null) {            result = Boolean.valueOf(auditSubclass(cl));            Caches.subclassAudits.putIfAbsent(key, result);        }        return result.booleanValue();    }    /**     * Performs reflective checks on given subclass to verify that it doesn't     * override security-sensitive non-final methods.  Returns true if the     * subclass overrides any of the methods, false otherwise.     */    private static boolean auditSubclass(final Class subcl) {        Boolean result = AccessController.doPrivileged(            new PrivilegedAction<Boolean>() {                public Boolean run() {                    for (Class cl = subcl;                         cl != Thread.class;                         cl = cl.getSuperclass())                    {                        try {                            cl.getDeclaredMethod("getContextClassLoader", new Class[0]);                            return Boolean.TRUE;                        } catch (NoSuchMethodException ex) {                        }                        try {                            Class[] params = {ClassLoader.class};                            cl.getDeclaredMethod("setContextClassLoader", params);                            return Boolean.TRUE;                        } catch (NoSuchMethodException ex) {                        }                    }                    return Boolean.FALSE;                }            }        );        return result.booleanValue();    }    private native static StackTraceElement[][] dumpThreads(Thread[] threads);    private native static Thread[] getThreads();    /**     * Returns the identifier of this Thread.  The thread ID is a positive     * <tt>long</tt> number generated when this thread was created.     * The thread ID is unique and remains unchanged during its lifetime.     * When a thread is terminated, this thread ID may be reused.     *     * @return this thread's ID.     * @since 1.5     */    public long getId() {        return tid;    }    /**     * A thread state.  A thread can be in one of the following states:     * <ul>     * <li>{@link #NEW}<br>     *     A thread that has not yet started is in this state.     *     </li>     * <li>{@link #RUNNABLE}<br>     *     A thread executing in the Java virtual machine is in this state.     *     </li>     * <li>{@link #BLOCKED}<br>     *     A thread that is blocked waiting for a monitor lock     *     is in this state.     *     </li>     * <li>{@link #WAITING}<br>     *     A thread that is waiting indefinitely for another thread to     *     perform a particular action is in this state.     *     </li>     * <li>{@link #TIMED_WAITING}<br>     *     A thread that is waiting for another thread to perform an action     *     for up to a specified waiting time is in this state.     *     </li>     * <li>{@link #TERMINATED}<br>     *     A thread that has exited is in this state.     *     </li>     * </ul>     *     * <p>     * A thread can be in only one state at a given point in time.     * These states are virtual machine states which do not reflect     * any operating system thread states.     *     * @since   1.5     * @see #getState     */    public enum State {        /**         * Thread state for a thread which has not yet started.         */        NEW,        /**         * Thread state for a runnable thread.  A thread in the runnable         * state is executing in the Java virtual machine but it may         * be waiting for other resources from the operating system         * such as processor.         */        RUNNABLE,        /**         * Thread state for a thread blocked waiting for a monitor lock.         * A thread in the blocked state is waiting for a monitor lock         * to enter a synchronized block/method or         * reenter a synchronized block/method after calling         * {@link Object#wait() Object.wait}.         */        BLOCKED,        /**         * Thread state for a waiting thread.         * A thread is in the waiting state due to calling one of the         * following methods:         * <ul>         *   <li>{@link Object#wait() Object.wait} with no timeout</li>         *   <li>{@link #join() Thread.join} with no timeout</li>         *   <li>{@link LockSupport#park() LockSupport.park}</li>         * </ul>         *         * <p>A thread in the waiting state is waiting for another thread to         * perform a particular action.         *         * For example, a thread that has called <tt>Object.wait()</tt>         * on an object is waiting for another thread to call         * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on         * that object. A thread that has called <tt>Thread.join()</tt>         * is waiting for a specified thread to terminate.         */        WAITING,        /**         * Thread state for a waiting thread with a specified waiting time.         * A thread is in the timed waiting state due to calling one of         * the following methods with a specified positive waiting time:         * <ul>         *   <li>{@link #sleep Thread.sleep}</li>         *   <li>{@link Object#wait(long) Object.wait} with timeout</li>         *   <li>{@link #join(long) Thread.join} with timeout</li>         *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>         *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>         * </ul>         */        TIMED_WAITING,        /**         * Thread state for a terminated thread.         * The thread has completed execution.         */        TERMINATED;    }    /**     * Returns the state of this thread.     * This method is designed for use in monitoring of the system state,     * not for synchronization control.     *     * @return this thread's state.     * @since 1.5     */    public State getState() {        // get current thread state        return sun.misc.VM.toThreadState(threadStatus);    }    // Added in JSR-166    /**     * Interface for handlers invoked when a <tt>Thread</tt> abruptly     * terminates due to an uncaught exception.     * <p>When a thread is about to terminate due to an uncaught exception     * the Java Virtual Machine will query the thread for its     * <tt>UncaughtExceptionHandler</tt> using     * {@link #getUncaughtExceptionHandler} and will invoke the handler's     * <tt>uncaughtException</tt> method, passing the thread and the     * exception as arguments.     * If a thread has not had its <tt>UncaughtExceptionHandler</tt>     * explicitly set, then its <tt>ThreadGroup</tt> object acts as its     * <tt>UncaughtExceptionHandler</tt>. If the <tt>ThreadGroup</tt> object     * has no     * special requirements for dealing with the exception, it can forward     * the invocation to the {@linkplain #getDefaultUncaughtExceptionHandler     * default uncaught exception handler}.     *     * @see #setDefaultUncaughtExceptionHandler     * @see #setUncaughtExceptionHandler     * @see ThreadGroup#uncaughtException     * @since 1.5     */    public interface UncaughtExceptionHandler {        /**         * Method invoked when the given thread terminates due to the         * given uncaught exception.         * <p>Any exception thrown by this method will be ignored by the         * Java Virtual Machine.         * @param t the thread         * @param e the exception         */        void uncaughtException(Thread t, Throwable e);    }    // null unless explicitly set    private volatile UncaughtExceptionHandler uncaughtExceptionHandler;    // null unless explicitly set    private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;    /**     * Set the default handler invoked when a thread abruptly terminates     * due to an uncaught exception, and no other handler has been defined     * for that thread.     *     * <p>Uncaught exception handling is controlled first by the thread, then     * by the thread's {@link ThreadGroup} object and finally by the default     * uncaught exception handler. If the thread does not have an explicit     * uncaught exception handler set, and the thread's thread group     * (including parent thread groups)  does not specialize its     * <tt>uncaughtException</tt> method, then the default handler's     * <tt>uncaughtException</tt> method will be invoked.     * <p>By setting the default uncaught exception handler, an application     * can change the way in which uncaught exceptions are handled (such as     * logging to a specific device, or file) for those threads that would     * already accept whatever "default" behavior the system     * provided.     *     * <p>Note that the default uncaught exception handler should not usually     * defer to the thread's <tt>ThreadGroup</tt> object, as that could cause     * infinite recursion.     *     * @param eh the object to use as the default uncaught exception handler.     * If <tt>null</tt> then there is no default handler.     *     * @throws SecurityException if a security manager is present and it     *         denies <tt>{@link RuntimePermission}     *         ("setDefaultUncaughtExceptionHandler")</tt>     *     * @see #setUncaughtExceptionHandler     * @see #getUncaughtExceptionHandler     * @see ThreadGroup#uncaughtException     * @since 1.5     */    public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {        SecurityManager sm = System.getSecurityManager();        if (sm != null) {            sm.checkPermission(                new RuntimePermission("setDefaultUncaughtExceptionHandler")                    );        }         defaultUncaughtExceptionHandler = eh;     }    /**     * Returns the default handler invoked when a thread abruptly terminates     * due to an uncaught exception. If the returned value is <tt>null</tt>,     * there is no default.     * @since 1.5     * @see #setDefaultUncaughtExceptionHandler     */    public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){        return defaultUncaughtExceptionHandler;    }    /**     * Returns the handler invoked when this thread abruptly terminates     * due to an uncaught exception. If this thread has not had an     * uncaught exception handler explicitly set then this thread's     * <tt>ThreadGroup</tt> object is returned, unless this thread     * has terminated, in which case <tt>null</tt> is returned.     * @since 1.5     */    public UncaughtExceptionHandler getUncaughtExceptionHandler() {        return uncaughtExceptionHandler != null ?            uncaughtExceptionHandler : group;    }    /**     * Set the handler invoked when this thread abruptly terminates     * due to an uncaught exception.     * <p>A thread can take full control of how it responds to uncaught     * exceptions by having its uncaught exception handler explicitly set.     * If no such handler is set then the thread's <tt>ThreadGroup</tt>     * object acts as its handler.     * @param eh the object to use as this thread's uncaught exception     * handler. If <tt>null</tt> then this thread has no explicit handler.     * @throws  SecurityException  if the current thread is not allowed to     *          modify this thread.     * @see #setDefaultUncaughtExceptionHandler     * @see ThreadGroup#uncaughtException     * @since 1.5     */    public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {        checkAccess();        uncaughtExceptionHandler = eh;    }    /**     * Dispatch an uncaught exception to the handler. This method is     * intended to be called only by the JVM.     */    private void dispatchUncaughtException(Throwable e) {        getUncaughtExceptionHandler().uncaughtException(this, e);    }    /**     * Removes from the specified map any keys that have been enqueued     * on the specified reference queue.     */    static void processQueue(ReferenceQueue<Class<?>> queue,                             ConcurrentMap<? extends                             WeakReference<Class<?>>, ?> map)    {        Reference<? extends Class<?>> ref;        while((ref = queue.poll()) != null) {            map.remove(ref);        }    }    /**     *  Weak key for Class objects.     **/    static class WeakClassKey extends WeakReference<Class<?>> {        /**         * saved value of the referent's identity hash code, to maintain         * a consistent hash code after the referent has been cleared         */        private final int hash;        /**         * Create a new WeakClassKey to the given object, registered         * with a queue.         */        WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {            super(cl, refQueue);            hash = System.identityHashCode(cl);        }        /**         * Returns the identity hash code of the original referent.         */        @Override        public int hashCode() {            return hash;        }        /**         * Returns true if the given object is this identical         * WeakClassKey instance, or, if this object's referent has not         * been cleared, if the given object is another WeakClassKey         * instance with the identical non-null referent as this one.         */        @Override        public boolean equals(Object obj) {            if (obj == this)                return true;            if (obj instanceof WeakClassKey) {                Object referent = get();                return (referent != null) &&                       (referent == ((WeakClassKey) obj).get());            } else {                return false;            }        }    }    /* Some private helper methods */    private native void setPriority0(int newPriority);    private native void stop0(Object o);    private native void suspend0();    private native void resume0();    private native void interrupt0();    private native void setNativeName(String name);}

原创粉丝点击