Partially updated to OpenJDK 7.

This commit is contained in:
jfrijters 2011-06-17 12:32:06 +00:00
Родитель 5d07ae3795
Коммит 67d11a210b
1 изменённых файлов: 338 добавлений и 271 удалений

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -30,7 +30,6 @@ import java.security.AccessControlContext;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.util.Map; import java.util.Map;
import java.util.HashMap; import java.util.HashMap;
import java.util.Collections;
import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.LockSupport;
import sun.nio.ch.Interruptible; import sun.nio.ch.Interruptible;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
@ -119,6 +118,10 @@ import sun.security.util.SecurityConstants;
* Every thread has a name for identification purposes. More than * Every thread has a name for identification purposes. More than
* one thread may have the same name. If a name is not specified when * 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. * 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 * @author unascribed
* @see Runnable * @see Runnable
@ -224,6 +227,7 @@ class Thread implements Runnable {
private volatile int threadStatus = 0; private volatile int threadStatus = 0;
private static synchronized long nextThreadID() { private static synchronized long nextThreadID() {
return ++threadSeqNumber; return ++threadSeqNumber;
} }
@ -241,7 +245,7 @@ class Thread implements Runnable {
* after setting this thread's interrupt status. * after setting this thread's interrupt status.
*/ */
private volatile Interruptible blocker; private volatile Interruptible blocker;
private Object blockerLock = new Object(); private final Object blockerLock = new Object();
/* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code /* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code
*/ */
@ -272,10 +276,6 @@ class Thread implements Runnable {
/* Remembered Throwable from stop before start */ /* Remembered Throwable from stop before start */
private Throwable throwableFromStop; private Throwable throwableFromStop;
/* Whether or not the Thread has been completely constructed;
* init or clone method has successfully completed */
private volatile Thread me; // null
/** /**
* Returns a reference to the currently executing thread object. * Returns a reference to the currently executing thread object.
* *
@ -292,8 +292,20 @@ class Thread implements Runnable {
private static native ThreadGroup getMainThreadGroup(); private static native ThreadGroup getMainThreadGroup();
/** /**
* Causes the currently executing thread object to temporarily pause * A hint to the scheduler that the current thread is willing to yield
* and allow other threads to execute. * 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 void yield() { public static void yield() {
cli.System.Threading.Thread.Sleep(0); cli.System.Threading.Thread.Sleep(0);
@ -355,11 +367,16 @@ class Thread implements Runnable {
* the precision and accuracy of system timers and schedulers. The thread * the precision and accuracy of system timers and schedulers. The thread
* does not lose ownership of any monitors. * does not lose ownership of any monitors.
* *
* @param millis the length of time to sleep in milliseconds. * @param millis
* @exception InterruptedException if any thread has interrupted * the length of time to sleep in milliseconds
* the current thread. The <i>interrupted status</i> of the *
* current thread is cleared when this exception is thrown. * @throws IllegalArgumentException
* @see Object#notify() * 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 void sleep(long millis) throws InterruptedException { public static void sleep(long millis) throws InterruptedException {
if (millis < 0) { if (millis < 0) {
@ -383,21 +400,26 @@ class Thread implements Runnable {
} }
/** /**
* Causes the currently executing thread to sleep (cease execution) * Causes the currently executing thread to sleep (temporarily cease
* for the specified number of milliseconds plus the specified number * execution) for the specified number of milliseconds plus the specified
* of nanoseconds, subject to the precision and accuracy of system * number of nanoseconds, subject to the precision and accuracy of system
* timers and schedulers. The thread does not lose ownership of any * timers and schedulers. The thread does not lose ownership of any
* monitors. * monitors.
* *
* @param millis the length of time to sleep in milliseconds. * @param millis
* @param nanos 0-999999 additional nanoseconds to sleep. * the length of time to sleep in milliseconds
* @exception IllegalArgumentException if the value of millis is *
* negative or the value of nanos is not in the range * @param nanos
* 0-999999. * {@code 0-999999} additional nanoseconds to sleep
* @exception InterruptedException if any thread has interrupted *
* the current thread. The <i>interrupted status</i> of the * @throws IllegalArgumentException
* current thread is cleared when this exception is thrown. * if the value of {@code millis} is negative, or the value of
* @see Object#notify() * {@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) public static void sleep(long millis, int nanos)
throws InterruptedException { throws InterruptedException {
@ -428,6 +450,10 @@ class Thread implements Runnable {
*/ */
private void init(ThreadGroup g, Runnable target, String name, private void init(ThreadGroup g, Runnable target, String name,
long stackSize) { long stackSize) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}
Thread parent = currentThread(); Thread parent = currentThread();
SecurityManager security = System.getSecurityManager(); SecurityManager security = System.getSecurityManager();
if (g == null) { if (g == null) {
@ -481,8 +507,6 @@ class Thread implements Runnable {
/* Set thread ID */ /* Set thread ID */
tid = nextThreadID(); tid = nextThreadID();
this.me = this;
} }
// [IKVM] constructor for attaching to a .NET thread // [IKVM] constructor for attaching to a .NET thread
@ -516,8 +540,6 @@ class Thread implements Runnable {
if (!daemon) { if (!daemon) {
cli.System.Threading.Interlocked.Increment(nonDaemonCount); cli.System.Threading.Interlocked.Increment(nonDaemonCount);
} }
this.me = this;
} }
private static int mapClrPriorityToJava(int priority) { private static int mapClrPriorityToJava(int priority) {
@ -561,196 +583,186 @@ class Thread implements Runnable {
} }
/** /**
* Returns a clone if the class of this object is {@link Cloneable Cloneable}. * Throws CloneNotSupportedException as a Thread can not be meaningfully
* * cloned. Construct a new Thread instead.
* @return a clone if the class of this object is {@code Cloneable}
* *
* @throws CloneNotSupportedException * @throws CloneNotSupportedException
* if this method is invoked on a class that does not * always
* support {@code Cloneable}
*/ */
@Override @Override
protected Object clone() throws CloneNotSupportedException { protected Object clone() throws CloneNotSupportedException {
Thread t; throw new CloneNotSupportedException();
synchronized(this) {
t = (Thread) super.clone();
t.tid = nextThreadID();
t.parkBlocker = null;
t.blocker = null;
t.blockerLock = new Object();
t.threadLocals = null;
group.checkAccess();
if (threadStatus == 0) {
group.addUnstarted();
}
t.setPriority(priority);
final Thread current = Thread.currentThread();
if (current.inheritableThreadLocals != null)
t.inheritableThreadLocals =
ThreadLocal.createInheritedMap(current.inheritableThreadLocals);
}
t.me = t;
return t;
} }
/** /**
* Allocates a new <code>Thread</code> object. This constructor has * Allocates a new {@code Thread} object. This constructor has the same
* the same effect as <code>Thread(null, null,</code> * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
* <i>gname</i><code>)</code>, where <b><i>gname</i></b> is * {@code (null, null, gname)}, where {@code gname} is a newly generated
* a newly generated name. Automatically generated names are of the * name. Automatically generated names are of the form
* form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer. * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
*
* @see #Thread(ThreadGroup, Runnable, String)
*/ */
public Thread() { public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0); init(null, null, "Thread-" + nextThreadNum(), 0);
} }
/** /**
* Allocates a new <code>Thread</code> object. This constructor has * Allocates a new {@code Thread} object. This constructor has the same
* the same effect as <code>Thread(null, target,</code> * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
* <i>gname</i><code>)</code>, where <i>gname</i> is * {@code (null, target, gname)}, where {@code gname} is a newly generated
* a newly generated name. Automatically generated names are of the * name. Automatically generated names are of the form
* form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer. * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
* *
* @param target the object whose <code>run</code> method is called. * @param target
* @see #Thread(ThreadGroup, Runnable, String) * 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) { public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0); init(null, target, "Thread-" + nextThreadNum(), 0);
} }
/** /**
* Allocates a new <code>Thread</code> object. This constructor has * Allocates a new {@code Thread} object. This constructor has the same
* the same effect as <code>Thread(group, target,</code> * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
* <i>gname</i><code>)</code>, where <i>gname</i> is * {@code (group, target, gname)} ,where {@code gname} is a newly generated
* a newly generated name. Automatically generated names are of the * name. Automatically generated names are of the form
* form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer. * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
* *
* @param group the thread group. * @param group
* @param target the object whose <code>run</code> method is called. * the thread group. If {@code null} and there is a security
* @exception SecurityException if the current thread cannot create a * manager, the group is determined by {@linkplain
* thread in the specified thread group. * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
* @see #Thread(ThreadGroup, Runnable, String) * 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) { public Thread(ThreadGroup group, Runnable target) {
init(group, target, "Thread-" + nextThreadNum(), 0); init(group, target, "Thread-" + nextThreadNum(), 0);
} }
/** /**
* Allocates a new <code>Thread</code> object. This constructor has * Allocates a new {@code Thread} object. This constructor has the same
* the same effect as <code>Thread(null, null, name)</code>. * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
* {@code (null, null, name)}.
* *
* @param name the name of the new thread. * @param name
* @see #Thread(ThreadGroup, Runnable, String) * the name of the new thread
*/ */
public Thread(String name) { public Thread(String name) {
init(null, null, name, 0); init(null, null, name, 0);
} }
/** /**
* Allocates a new <code>Thread</code> object. This constructor has * Allocates a new {@code Thread} object. This constructor has the same
* the same effect as <code>Thread(group, null, name)</code> * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
* {@code (group, null, name)}.
* *
* @param group the thread group. * @param group
* @param name the name of the new thread. * the thread group. If {@code null} and there is a security
* @exception SecurityException if the current thread cannot create a * manager, the group is determined by {@linkplain
* thread in the specified thread group. * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
* @see #Thread(ThreadGroup, Runnable, String) * 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) { public Thread(ThreadGroup group, String name) {
init(group, null, name, 0); init(group, null, name, 0);
} }
/** /**
* Allocates a new <code>Thread</code> object. This constructor has * Allocates a new {@code Thread} object. This constructor has the same
* the same effect as <code>Thread(null, target, name)</code>. * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
* {@code (null, target, name)}.
* *
* @param target the object whose <code>run</code> method is called. * @param target
* @param name the name of the new thread. * the object whose {@code run} method is invoked when this thread
* @see #Thread(ThreadGroup, Runnable, String) * 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) { public Thread(Runnable target, String name) {
init(null, target, name, 0); init(null, target, name, 0);
} }
/** /**
* Allocates a new <code>Thread</code> object so that it has * Allocates a new {@code Thread} object so that it has {@code target}
* <code>target</code> as its run object, has the specified * as its run object, has the specified {@code name} as its name,
* <code>name</code> as its name, and belongs to the thread group * and belongs to the thread group referred to by {@code group}.
* referred to by <code>group</code>.
* <p>
* If <code>group</code> is <code>null</code> and there is a
* security manager, the group is determined by the security manager's
* <code>getThreadGroup</code> method. If <code>group</code> is
* <code>null</code> and there is not a security manager, or the
* security manager's <code>getThreadGroup</code> method returns
* <code>null</code>, the group is set to be the same ThreadGroup
* as the thread that is creating the new thread.
* *
* <p>If there is a security manager, its <code>checkAccess</code> * <p>If there is a security manager, its
* method is called with the ThreadGroup as its argument. * {@link SecurityManager#checkAccess(ThreadGroup) checkAccess}
* <p>In addition, its <code>checkPermission</code> * method is invoked with the ThreadGroup as its argument.
* method is called with the *
* <code>RuntimePermission("enableContextClassLoaderOverride")</code> * <p>In addition, its {@code checkPermission} method is invoked with
* the {@code RuntimePermission("enableContextClassLoaderOverride")}
* permission when invoked directly or indirectly by the constructor * permission when invoked directly or indirectly by the constructor
* of a subclass which overrides the <code>getContextClassLoader</code> * of a subclass which overrides the {@code getContextClassLoader}
* or <code>setContextClassLoader</code> methods. * or {@code setContextClassLoader} methods.
* This may result in a SecurityException.
* <p>
* If the <code>target</code> argument is not <code>null</code>, the
* <code>run</code> method of the <code>target</code> is called when
* this thread is started. If the target argument is
* <code>null</code>, this thread's <code>run</code> method is called
* when this thread is started.
* <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 <code>setPriority</code> 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 <code>setDaemon </code> may be used
* to change whether or not a thread is a daemon.
* *
* @param group the thread group. * <p>The priority of the newly created thread is set equal to the
* @param target the object whose <code>run</code> method is called. * priority of the thread creating it, that is, the currently running
* @param name the name of the new thread. * thread. The method {@linkplain #setPriority setPriority} may be
* @exception SecurityException if the current thread cannot create a * used to change the priority to a new value.
* thread in the specified thread group or cannot *
* override the context class loader methods. * <p>The newly created thread is initially marked as being a daemon
* @see Runnable#run() * thread if and only if the thread creating it is currently marked
* @see #run() * as a daemon thread. The method {@linkplain #setDaemon setDaemon}
* @see #setDaemon(boolean) * may be used to change whether or not a thread is a daemon.
* @see #setPriority(int) *
* @see ThreadGroup#checkAccess() * @param group
* @see SecurityManager#checkAccess * 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) { public Thread(ThreadGroup group, Runnable target, String name) {
init(group, target, name, 0); init(group, target, name, 0);
} }
/** /**
* Allocates a new <code>Thread</code> object so that it has * Allocates a new {@code Thread} object so that it has {@code target}
* <code>target</code> as its run object, has the specified * as its run object, has the specified {@code name} as its name,
* <code>name</code> as its name, belongs to the thread group referred to * and belongs to the thread group referred to by {@code group}, and has
* by <code>group</code>, and has the specified <i>stack size</i>. * the specified <i>stack size</i>.
* *
* <p>This constructor is identical to {@link * <p>This constructor is identical to {@link
* #Thread(ThreadGroup,Runnable,String)} with the exception of the fact * #Thread(ThreadGroup,Runnable,String)} with the exception of the fact
* that it allows the thread stack size to be specified. The stack size * 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 * 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 * machine is to allocate for this thread's stack. <b>The effect of the
* <tt>stackSize</tt> parameter, if any, is highly platform dependent.</b> * {@code stackSize} parameter, if any, is highly platform dependent.</b>
* *
* <p>On some platforms, specifying a higher value for the * <p>On some platforms, specifying a higher value for the
* <tt>stackSize</tt> parameter may allow a thread to achieve greater * {@code stackSize} parameter may allow a thread to achieve greater
* recursion depth before throwing a {@link StackOverflowError}. * recursion depth before throwing a {@link StackOverflowError}.
* Similarly, specifying a lower value may allow a greater number of * Similarly, specifying a lower value may allow a greater number of
* threads to exist concurrently without throwing an {@link * threads to exist concurrently without throwing an {@link
@ -758,9 +770,9 @@ class Thread implements Runnable {
* the relationship between the value of the <tt>stackSize</tt> parameter * the relationship between the value of the <tt>stackSize</tt> parameter
* and the maximum recursion depth and concurrency level are * and the maximum recursion depth and concurrency level are
* platform-dependent. <b>On some platforms, the value of the * platform-dependent. <b>On some platforms, the value of the
* <tt>stackSize</tt> parameter may have no effect whatsoever.</b> * {@code stackSize} parameter may have no effect whatsoever.</b>
* *
* <p>The virtual machine is free to treat the <tt>stackSize</tt> * <p>The virtual machine is free to treat the {@code stackSize}
* parameter as a suggestion. If the specified value is unreasonably low * parameter as a suggestion. If the specified value is unreasonably low
* for the platform, the virtual machine may instead use some * for the platform, the virtual machine may instead use some
* platform-specific minimum value; if the specified value is unreasonably * platform-specific minimum value; if the specified value is unreasonably
@ -768,9 +780,9 @@ class Thread implements Runnable {
* maximum. Likewise, the virtual machine is free to round the specified * maximum. Likewise, the virtual machine is free to round the specified
* value up or down as it sees fit (or to ignore it completely). * value up or down as it sees fit (or to ignore it completely).
* *
* <p>Specifying a value of zero for the <tt>stackSize</tt> parameter will * <p>Specifying a value of zero for the {@code stackSize} parameter will
* cause this constructor to behave exactly like the * cause this constructor to behave exactly like the
* <tt>Thread(ThreadGroup, Runnable, String)</tt> constructor. * {@code Thread(ThreadGroup, Runnable, String)} constructor.
* *
* <p><i>Due to the platform-dependent nature of the behavior of this * <p><i>Due to the platform-dependent nature of the behavior of this
* constructor, extreme care should be exercised in its use. * constructor, extreme care should be exercised in its use.
@ -782,15 +794,32 @@ class Thread implements Runnable {
* *
* <p>Implementation note: Java platform implementers are encouraged to * <p>Implementation note: Java platform implementers are encouraged to
* document their implementation's behavior with respect to the * document their implementation's behavior with respect to the
* <tt>stackSize parameter</tt>. * {@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
* *
* @param group the thread group.
* @param target the object whose <code>run</code> method is 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.
* @exception SecurityException if the current thread cannot create a
* thread in the specified thread group.
* @since 1.4 * @since 1.4
*/ */
public Thread(ThreadGroup group, Runnable target, String name, public Thread(ThreadGroup group, Runnable target, String name,
@ -824,7 +853,7 @@ class Thread implements Runnable {
* *
* A zero status value corresponds to state "NEW". * A zero status value corresponds to state "NEW".
*/ */
if (threadStatus != 0 || this != me) if (threadStatus != 0)
throw new IllegalThreadStateException(); throw new IllegalThreadStateException();
group.add(this); group.add(this);
start0(); start0();
@ -876,6 +905,7 @@ class Thread implements Runnable {
* @see #stop() * @see #stop()
* @see #Thread(ThreadGroup, Runnable, String) * @see #Thread(ThreadGroup, Runnable, String)
*/ */
@Override
public void run() { public void run() {
if (target != null) { if (target != null) {
target.run(); target.run();
@ -1027,12 +1057,7 @@ class Thread implements Runnable {
*/ */
@Deprecated @Deprecated
public final void stop() { public final void stop() {
// If the thread is already dead, return. stop(new ThreadDeath());
// A zero status value corresponds to "NEW".
if ((threadStatus != 0) && !isAlive()) {
return;
}
stop1(new ThreadDeath());
} }
/** /**
@ -1086,35 +1111,32 @@ class Thread implements Runnable {
*/ */
@Deprecated @Deprecated
public final synchronized void stop(Throwable obj) { public final synchronized void stop(Throwable obj) {
stop1(obj); if (obj == null)
} throw new NullPointerException();
/**
* Common impl for stop() and stop(Throwable).
*/
private final synchronized void stop1(Throwable th) {
SecurityManager security = System.getSecurityManager(); SecurityManager security = System.getSecurityManager();
if (security != null) { if (security != null) {
checkAccess(); checkAccess();
if ((this != Thread.currentThread()) || if ((this != Thread.currentThread()) ||
(!(th instanceof ThreadDeath))) { (!(obj instanceof ThreadDeath))) {
security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION); security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
} }
} }
// A zero status value corresponds to "NEW" // A zero status value corresponds to "NEW", it can't change to
// not-NEW because we hold the lock.
if (threadStatus != 0) { if (threadStatus != 0) {
resume(); // Wake up thread if it was suspended; no-op otherwise resume(); // Wake up thread if it was suspended; no-op otherwise
stop0(th); stop0(obj);
} else { } else {
// Must do the null arg check that the VM would do with stop0 // Must do the null arg check that the VM would do with stop0
if (th == null) { if (obj == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
// Remember this stop attempt for if/when start is used // Remember this stop attempt for if/when start is used
stopBeforeStart = true; stopBeforeStart = true;
throwableFromStop = th; throwableFromStop = obj;
} }
} }
@ -1403,34 +1425,50 @@ class Thread implements Runnable {
} }
/** /**
* Returns the number of active threads in the current thread's thread * Returns an estimate of the number of active threads in the current
* group. * thread's {@linkplain java.lang.ThreadGroup thread group} and its
* subgroups. Recursively iterates over all subgroups in the current
* thread's thread group.
* *
* @return the number of active threads in the current thread's thread * <p> The value returned is only an estimate because the number of
* group. * 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() { public static int activeCount() {
return currentThread().getThreadGroup().activeCount(); return currentThread().getThreadGroup().activeCount();
} }
/** /**
* Copies into the specified array every active thread in * Copies into the specified array every active thread in the current
* the current thread's thread group and its subgroups. This method simply * thread's thread group and its subgroups. This method simply
* calls the <code>enumerate</code> method of the current thread's thread * invokes the {@link java.lang.ThreadGroup#enumerate(Thread[])}
* group with the array argument. * method of the current thread's thread group.
* <p> *
* First, if there is a security manager, that <code>enumerate</code> * <p> An application might use the {@linkplain #activeCount activeCount}
* method calls the security * method to get an estimate of how big the array should be, however
* manager's <code>checkAccess</code> method * <i>if the array is too short to hold all the threads, the extra threads
* with the thread group as its argument. This may result * are silently ignored.</i> If it is critical to obtain every active
* in throwing a <code>SecurityException</code>. * 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
* *
* @param tarray an array of Thread objects to copy to
* @return the number of threads put into the array * @return the number of threads put into the array
* @exception SecurityException if a security manager exists and its *
* <code>checkAccess</code> method doesn't allow the operation. * @throws SecurityException
* @see ThreadGroup#enumerate(Thread[]) * if {@link java.lang.ThreadGroup#checkAccess} determines that
* @see SecurityManager#checkAccess(ThreadGroup) * the current thread cannot access its thread group
*/ */
public static int enumerate(Thread tarray[]) { public static int enumerate(Thread tarray[]) {
return currentThread().getThreadGroup().enumerate(tarray); return currentThread().getThreadGroup().enumerate(tarray);
@ -1453,13 +1491,25 @@ class Thread implements Runnable {
} }
/** /**
* Waits at most <code>millis</code> milliseconds for this thread to * Waits at most {@code millis} milliseconds for this thread to
* die. A timeout of <code>0</code> means to wait forever. * die. A timeout of {@code 0} means to wait forever.
* *
* @param millis the time to wait in milliseconds. * <p> This implementation uses a loop of {@code this.wait} calls
* @exception InterruptedException if any thread has interrupted * conditioned on {@code this.isAlive}. As a thread terminates the
* the current thread. The <i>interrupted status</i> of the * {@code this.notifyAll} method is invoked. It is recommended that
* current thread is cleared when this exception is thrown. * 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) public final synchronized void join(long millis)
throws InterruptedException { throws InterruptedException {
@ -1487,16 +1537,29 @@ class Thread implements Runnable {
} }
/** /**
* Waits at most <code>millis</code> milliseconds plus * Waits at most {@code millis} milliseconds plus
* <code>nanos</code> nanoseconds for this thread to die. * {@code nanos} nanoseconds for this thread to die.
* *
* @param millis the time to wait in milliseconds. * <p> This implementation uses a loop of {@code this.wait} calls
* @param nanos 0-999999 additional nanoseconds to wait. * conditioned on {@code this.isAlive}. As a thread terminates the
* @exception IllegalArgumentException if the value of millis is negative * {@code this.notifyAll} method is invoked. It is recommended that
* the value of nanos is not in the range 0-999999. * applications not use {@code wait}, {@code notify}, or
* @exception InterruptedException if any thread has interrupted * {@code notifyAll} on {@code Thread} instances.
* the current thread. The <i>interrupted status</i> of the *
* current thread is cleared when this exception is thrown. * @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) public final synchronized void join(long millis, int nanos)
throws InterruptedException { throws InterruptedException {
@ -1520,9 +1583,17 @@ class Thread implements Runnable {
/** /**
* Waits for this thread to die. * Waits for this thread to die.
* *
* @exception InterruptedException if any thread has interrupted * <p> An invocation of this method behaves in exactly the same
* the current thread. The <i>interrupted status</i> of the * way as the invocation
* current thread is cleared when this exception is thrown. *
* <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 { public final void join() throws InterruptedException {
join(0); join(0);
@ -1539,24 +1610,21 @@ class Thread implements Runnable {
} }
/** /**
* Marks this thread as either a daemon thread or a user thread. The * Marks this thread as either a {@linkplain #isDaemon daemon} thread
* Java Virtual Machine exits when the only threads running are all * or a user thread. The Java Virtual Machine exits when the only
* daemon threads. * threads running are all daemon threads.
* <p>
* This method must be called before the thread is started.
* <p>
* This method first calls the <code>checkAccess</code> method
* of this thread
* with no arguments. This may result in throwing a
* <code>SecurityException </code>(in the current thread).
* *
* @param on if <code>true</code>, marks this thread as a * <p> This method must be invoked before the thread is started.
* daemon thread. *
* @exception IllegalThreadStateException if this thread is active. * @param on
* @exception SecurityException if the current thread cannot modify * if {@code true}, marks this thread as a daemon thread
* this thread. *
* @see #isDaemon() * @throws IllegalThreadStateException
* @see #checkAccess * 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) { public final void setDaemon(boolean on) {
checkAccess(); checkAccess();
@ -1617,28 +1685,25 @@ class Thread implements Runnable {
* Returns the context ClassLoader for this Thread. The context * Returns the context ClassLoader for this Thread. The context
* ClassLoader is provided by the creator of the thread for use * ClassLoader is provided by the creator of the thread for use
* by code running in this thread when loading classes and resources. * by code running in this thread when loading classes and resources.
* If not set, the default is the ClassLoader context of the parent * If not {@linkplain #setContextClassLoader set}, the default is the
* Thread. The context ClassLoader of the primordial thread is * ClassLoader context of the parent Thread. The context ClassLoader of the
* typically set to the class loader used to load the application. * primordial thread is typically set to the class loader used to load the
* application.
* *
* <p>First, if there is a security manager, and the caller's class * <p>If a security manager is present, and the invoker's class loader is not
* loader is not null and the caller's class loader is not the same as or * {@code null} and is not the same as or an ancestor of the context class
* an ancestor of the context class loader for the thread whose * loader, then this method invokes the security manager's {@link
* context class loader is being requested, then the security manager's * SecurityManager#checkPermission(java.security.Permission) checkPermission}
* <code>checkPermission</code> * method with a {@link RuntimePermission RuntimePermission}{@code
* method is called with a * ("getClassLoader")} permission to verify that retrieval of the context
* <code>RuntimePermission("getClassLoader")</code> permission * class loader is permitted.
* to see if it's ok to get the context ClassLoader..
* *
* @return the context ClassLoader for this Thread * @return the context ClassLoader for this Thread, or {@code null}
* indicating the system class loader (or, failing that, the
* bootstrap class loader)
* *
* @throws SecurityException * @throws SecurityException
* if a security manager exists and its * if the current thread cannot get the context ClassLoader
* <code>checkPermission</code> method doesn't allow
* getting the context ClassLoader.
* @see #setContextClassLoader
* @see SecurityManager#checkPermission
* @see RuntimePermission
* *
* @since 1.2 * @since 1.2
*/ */
@ -1662,21 +1727,22 @@ class Thread implements Runnable {
/** /**
* Sets the context ClassLoader for this Thread. The context * Sets the context ClassLoader for this Thread. The context
* ClassLoader can be set when a thread is created, and allows * ClassLoader can be set when a thread is created, and allows
* the creator of the thread to provide the appropriate class loader * the creator of the thread to provide the appropriate class loader,
* to code running in the thread when loading classes and resources. * through {@code getContextClassLoader}, to code running in the thread
* when loading classes and resources.
* *
* <p>First, if there is a security manager, its <code>checkPermission</code> * <p>If a security manager is present, its {@link
* method is called with a * SecurityManager#checkPermission(java.security.Permission) checkPermission}
* <code>RuntimePermission("setContextClassLoader")</code> permission * method is invoked with a {@link RuntimePermission RuntimePermission}{@code
* to see if it's ok to set the context ClassLoader.. * ("setContextClassLoader")} permission to see if setting the context
* ClassLoader is permitted.
* *
* @param cl the context ClassLoader for this Thread * @param cl
* the context ClassLoader for this Thread, or null indicating the
* system class loader (or, failing that, the bootstrap class loader)
* *
* @exception SecurityException if the current thread cannot set the * @throws SecurityException
* context ClassLoader. * if the current thread cannot set the context ClassLoader
* @see #getContextClassLoader
* @see SecurityManager#checkPermission
* @see RuntimePermission
* *
* @since 1.2 * @since 1.2
*/ */
@ -1735,7 +1801,8 @@ class Thread implements Runnable {
/** /**
* Returns an array of stack trace elements representing the stack dump * Returns an array of stack trace elements representing the stack dump
* of this thread. This method will return a zero-length array if * of this thread. This method will return a zero-length array if
* this thread has not started or has terminated. * 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 * 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 * the array represents the top of the stack, which is the most recent
* method invocation in the sequence. The last element of the array * method invocation in the sequence. The last element of the array