java.lang.Thread Maven / Gradle / Ivy
/* * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.lang; import java.util.Map; /** * A thread is a thread of execution in a program. The Java * Virtual Machine allows an application to have multiple threads of * execution running concurrently. *
interruptible * channel* 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
Thread
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. ** When a Java Virtual Machine starts up, there is usually a single * non-daemon thread (which typically calls the method named *
main
of some designated class). The Java Virtual * Machine continues to execute threads until either of the following * occurs: **
*- The
exit
method of classRuntime
has been * called and the security manager has permitted the exit operation * to take place. *- All threads that are not daemon threads have died, either by * returning from the call to the
run
method or by * throwing an exception that propagates beyond therun
* method. ** There are two ways to create a new thread of execution. One is to * declare a class to be a subclass of
Thread
. This * subclass should override therun
method of class *Thread
. 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: ** class PrimeThread extends Thread { * long minPrime; * PrimeThread(long minPrime) { * this.minPrime = minPrime; * } * * public void run() { * // compute primes larger than minPrime * . . . * } * } *
** The following code would then create a thread and start it running: *
** PrimeThread p = new PrimeThread(143); * p.start(); ** The other way to create a thread is to declare a class that * implements the
Runnable
interface. That class then * implements therun
method. An instance of the class can * then be allocated, passed as an argument when creating *Thread
, and started. The same example in this other * style looks like the following: ** class PrimeRun implements Runnable { * long minPrime; * PrimeRun(long minPrime) { * this.minPrime = minPrime; * } * * public void run() { * // compute primes larger than minPrime * . . . * } * } *
** The following code would then create a thread and start it running: *
** PrimeRun p = new PrimeRun(143); * new Thread(p).start(); ** 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. *
* 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 */ public class Thread implements Runnable { /** * 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; private static final Thread ONE = new Thread("main"); /** * Returns a reference to the currently executing thread object. * * @return the currently executing thread. */ public static Thread currentThread() { return ONE; } /** * 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. * *
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. * *
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 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 * interrupted status 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 * interrupted status 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); } private Runnable target; private String name; /** * 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-"+}n, where n is an integer. */ public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0); } private static int nextThreadNum() { return -1; } /** * 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-"+}n, where n 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); } /** * 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-"+}n, where n 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); } private void init(Object o1, Runnable trgt, String nm, int i4) { this.target = trgt; this.name = nm; } /** * 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}. * *
If there is a security manager, its * {@link SecurityManager#checkAccess(ThreadGroup) checkAccess} * method is invoked with the ThreadGroup as its argument. * *
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. * *
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. * *
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 stack size. * *
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. The effect of the * {@code stackSize} parameter, if any, is highly platform dependent. * *
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 stackSize parameter * and the maximum recursion depth and concurrency level are * platform-dependent. On some platforms, the value of the * {@code stackSize} parameter may have no effect whatsoever. * *
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). * *
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. * *
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. * *
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
run
method of this thread. ** The result is that two threads are running concurrently: the * current thread (which returns from the call to the *
start
method) and the other thread (which executes its *run
method). ** 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 void start() { throw new SecurityException(); } /** * If this thread was constructed using a separate *
Runnable
run object, then that *Runnable
object'srun
method is called; * otherwise, this method does nothing and returns. ** Subclasses of
Thread
should override this method. * * @see #start() * @see #stop() * @see #Thread(ThreadGroup, Runnable, String) */ @Override public void run() { if (target != null) { target.run(); } } /** * Forces the thread to stop executing. ** If there is a security manager installed, its
checkAccess
* method is called withthis
* as its argument. This may result in a *SecurityException
being raised (in the current thread). ** 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
checkPermission
method (with a *RuntimePermission("stopThread")
argument) is called in * addition. * Again, this may result in throwing a *SecurityException
(in the current thread). ** The thread represented by this thread is forced to stop whatever * it is doing abnormally and to throw a newly created *
ThreadDeath
object as an exception. ** It is permitted to stop a thread that has not yet been started. * If the thread is eventually started, it immediately terminates. *
* An application should not normally try to catch *
ThreadDeath
unless it must do some extraordinary * cleanup operation (note that the throwing of *ThreadDeath
causesfinally
clauses of *try
statements to be executed before the thread * officially dies). If acatch
clause catches a *ThreadDeath
object, it is important to rethrow the * object so that the thread actually dies. ** 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 *
ThreadDeath
. * * @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 *ThreadDeath
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 ofstop
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), theinterrupt
method should be used to * interrupt the wait. * For more information, see * Why * are Thread.stop, Thread.suspend and Thread.resume Deprecated?. */ @Deprecated public final void stop() { stop(null); } /** * Forces the thread to stop executing. ** If there is a security manager installed, the
checkAccess
* method of this thread is called, which may result in a *SecurityException
being raised (in the current thread). ** If this thread is different from the current thread (that is, the current * thread is trying to stop a thread other than itself) or *
obj
is not an instance ofThreadDeath
, the * security manager'scheckPermission
method (with the *RuntimePermission("stopThread")
argument) is called in * addition. * Again, this may result in throwing a *SecurityException
(in the current thread). ** If the argument
obj
is null, a *NullPointerException
is thrown (in the current thread). ** The thread represented by this thread is forced to stop * whatever it is doing abnormally and to throw the *
Throwable
objectobj
as an exception. This * is an unusual action to take; normally, thestop
method * that takes no arguments should be used. ** 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 null. * @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 * Why * are Thread.stop, Thread.suspend and Thread.resume Deprecated?. */ @Deprecated public final synchronized void stop(Throwable obj) { throw new SecurityException(); } /** * Interrupts this thread. * *
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. * *
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}. * *
If this thread is blocked in an I/O operation upon an {@link * java.nio.channels.InterruptibleChannel
} 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}. * *
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. * *
If none of the previous conditions hold then this thread's interrupt * status will be set.
* *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() { throw new SecurityException(); } /** * Tests whether the current thread has been interrupted. The * interrupted status 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). * *
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
true
if the current thread has been interrupted; *false
otherwise. * @see #isInterrupted() * @revised 6.0 */ public static boolean interrupted() { return currentThread().isInterrupted(); } /** * Tests whether this thread has been interrupted. The interrupted * status of the thread is unaffected by this method. * *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
true
if this thread has been interrupted; *false
otherwise. * @see #interrupted() * @revised 6.0 */ public boolean isInterrupted() { return false; } /** * 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 * * Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?. * @throws NoSuchMethodError always */ @Deprecated public void destroy() { throw new SecurityException(); } /** * Tests if this thread is alive. A thread is alive if it has * been started and has not yet died. * * @returntrue
if this thread is alive; *false
otherwise. */ public final boolean isAlive() { return true; } /** * Suspends this thread. ** First, the
checkAccess
method of this thread is called * with no arguments. This may result in throwing a *SecurityException
(in the current thread). ** 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
resume
, deadlock results. Such * deadlocks typically manifest themselves as "frozen" processes. * For more information, see * Why * are Thread.stop, Thread.suspend and Thread.resume Deprecated?. */ @Deprecated public final void suspend() { checkAccess(); } /** * Resumes a suspended thread. ** First, the
checkAccess
method of this thread is called * with no arguments. This may result in throwing a *SecurityException
(in the current thread). ** 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 * Why * are Thread.stop, Thread.suspend and Thread.resume Deprecated?. */ @Deprecated public final void resume() { checkAccess(); } /** * Changes the priority of this thread. *
* First the
checkAccess
method of this thread is called * with no arguments. This may result in throwing a *SecurityException
. ** Otherwise, the priority of this thread is set to the smaller of * the specified
newPriority
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 * rangeMIN_PRIORITY
to *MAX_PRIORITY
. * @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) { throw new SecurityException(); } /** * Returns this thread's priority. * * @return this thread's priority. * @see #setPriority */ public final int getPriority() { return Thread.NORM_PRIORITY; } /** * Changes the name of this thread to be equal to the argument *name
. ** First the
checkAccess
method of this thread is called * with no arguments. This may result in throwing a *SecurityException
. * * @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) { throw new SecurityException(); } /** * 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. * *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 1; } /** * 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. * *
An application might use the {@linkplain #activeCount activeCount} * method to get an estimate of how big the array should be, however * if the array is too short to hold all the threads, the extra threads * are silently ignored. 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}. * *
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[]) { throw new SecurityException(); } /** * 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. * *
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 * interrupted status 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. * *
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 * interrupted status 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. * *
An invocation of this method behaves in exactly the same * way as the invocation * *
* {@linkplain #join(long) join}{@code (0)} ** * @throws InterruptedException * if any thread has interrupted the current thread. The * interrupted status 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. * *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) { throw new SecurityException(); } /** * Tests if this thread is a daemon thread. * * @return
true
if this thread is a daemon thread; *false
otherwise. * @see #setDaemon(boolean) */ public final boolean isDaemon() { return false; } /** * Determines if the currently running thread has permission to * modify this thread. ** If there is a security manager, its
checkAccess
method * is called with this thread as its argument. This may result in * throwing aSecurityException
. * * @exception SecurityException if the current thread is not allowed to * access this thread. * @see SecurityManager#checkAccess(Thread) */ public final void checkAccess() { throw new SecurityException(); } /** * 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() { 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. * *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 */ public ClassLoader getContextClassLoader() { return ClassLoader.getSystemClassLoader(); } /** * 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. * *
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) { if (cl == ClassLoader.getSystemClassLoader()) { return; } throw new SecurityException(); } /** * Returns true if and only if the current thread holds the * monitor lock on the specified object. * *
This method is designed to allow a program to assert that * the current thread already holds a specified lock: *
* assert Thread.holdsLock(obj); ** * @param obj the object on which to test lock ownership * @throws NullPointerException if obj is null * @return true if the current thread holds the monitor lock on * the specified object. * @since 1.4 */ public static boolean holdsLock(Object obj) { return true; } /** * 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. * *If there is a security manager, and this thread is not * the current thread, then the security manager's * checkPermission method is called with a * RuntimePermission("getStackTrace") permission * to see if it's ok to get the stack trace. * *
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 StackTraceElement, * each represents one stack frame. * * @throws SecurityException * if a security manager exists and its * checkPermission method doesn't allow * getting the stack trace of thread. * @see SecurityManager#checkPermission * @see RuntimePermission * @see Throwable#getStackTrace * * @since 1.5 */ public StackTraceElement[] getStackTrace() { throw new SecurityException(); } /** * Returns a map of stack traces for all live threads. * The map keys are threads and each map value is an array of * StackTraceElement that represents the stack dump * of the corresponding Thread. * The returned stack traces are in the format specified for * the {@link #getStackTrace getStackTrace} method. * *
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. * *
If there is a security manager, then the security manager's * checkPermission method is called with a * RuntimePermission("getStackTrace") permission as well as * RuntimePermission("modifyThreadGroup") permission * to see if it is ok to get the stack trace of all threads. * * @return a Map from Thread to an array of * StackTraceElement that represents the stack trace of * the corresponding thread. * * @throws SecurityException * if a security manager exists and its * checkPermission 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
getAllStackTraces() { throw new SecurityException(); } /** * Returns the identifier of this Thread. The thread ID is a positive * long 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 0; } /** * A thread state. A thread can be in one of the following states: * *
* *- {@link #NEW}
*
* A thread that has not yet started is in this state. *- {@link #RUNNABLE}
*
* A thread executing in the Java virtual machine is in this state. *- {@link #BLOCKED}
*
* A thread that is blocked waiting for a monitor lock * is in this state. *- {@link #WAITING}
*
* A thread that is waiting indefinitely for another thread to * perform a particular action is in this state. *- {@link #TIMED_WAITING}
*
* A thread that is waiting for another thread to perform an action * for up to a specified waiting time is in this state. *- {@link #TERMINATED}
*
* A thread that has exited is in this state. ** 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: *
*
* *- {@link Object#wait() Object.wait} with no timeout
*- {@link #join() Thread.join} with no timeout
*- {@link LockSupport#park() LockSupport.park}
*A thread in the waiting state is waiting for another thread to * perform a particular action. * * For example, a thread that has called Object.wait() * on an object is waiting for another thread to call * Object.notify() or Object.notifyAll() on * that object. A thread that has called Thread.join() * 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: *
*
*/ 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 State.RUNNABLE; } // Added in JSR-166 /** * Interface for handlers invoked when a Thread abruptly * terminates due to an uncaught exception. *- {@link #sleep Thread.sleep}
*- {@link Object#wait(long) Object.wait} with timeout
*- {@link #join(long) Thread.join} with timeout
*- {@link LockSupport#parkNanos LockSupport.parkNanos}
*- {@link LockSupport#parkUntil LockSupport.parkUntil}
*When a thread is about to terminate due to an uncaught exception * the Java Virtual Machine will query the thread for its * UncaughtExceptionHandler using * {@link #getUncaughtExceptionHandler} and will invoke the handler's * uncaughtException method, passing the thread and the * exception as arguments. * If a thread has not had its UncaughtExceptionHandler * explicitly set, then its ThreadGroup object acts as its * UncaughtExceptionHandler. If the ThreadGroup 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. *
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. * *
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 * uncaughtException method, then the default handler's * uncaughtException method will be invoked. *
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. * *
Note that the default uncaught exception handler should not usually * defer to the thread's ThreadGroup object, as that could cause * infinite recursion. * * @param eh the object to use as the default uncaught exception handler. * If null then there is no default handler. * * @throws SecurityException if a security manager is present and it * denies {@link RuntimePermission} * ("setDefaultUncaughtExceptionHandler") * * @see #setUncaughtExceptionHandler * @see #getUncaughtExceptionHandler * @see ThreadGroup#uncaughtException * @since 1.5 */ public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) { throw new SecurityException(); } /** * Returns the default handler invoked when a thread abruptly terminates * due to an uncaught exception. If the returned value is null, * 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 * ThreadGroup object is returned, unless this thread * has terminated, in which case null is returned. * @since 1.5 */ public UncaughtExceptionHandler getUncaughtExceptionHandler() { return uncaughtExceptionHandler != null ? uncaughtExceptionHandler : null; } /** * Set the handler invoked when this thread abruptly terminates * due to an uncaught exception. *
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 ThreadGroup * object acts as its handler. * @param eh the object to use as this thread's uncaught exception * handler. If null 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; } }