Thread class in java Thread class internal coding Thread class methods and variables in java
/ /javajavax Copy writes
package java.lang;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.AccessControlContext;
import java.security.PrivilegedAction;
import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.LockSupport;
import sun.nio.ch.Interruptible;
import sun.security.util.SecurityConstants;
public class Thread implements Runnable {
private static
native void registerNatives();
static {
registerNatives();
}
private char name[];
private int priority;
private
Thread threadQ;
private long eetop;
private
boolean single_step;
private
boolean daemon = false;
private
boolean stillborn = false;
private Runnable
target;
private
ThreadGroup group;
private
ClassLoader contextClassLoader;
private
AccessControlContext inheritedAccessControlContext;
private static int
threadInitNumber;
private static
synchronized int nextThreadNum() {
return
threadInitNumber++;
}
ThreadLocal.ThreadLocalMap threadLocals = null;
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
private long
stackSize;
private long
nativeParkEventPointer;
private long tid;
private static
long threadSeqNumber;
private int
threadStatus = 0;
private static
synchronized long nextThreadID() {
return
++threadSeqNumber;
}
volatile Object
parkBlocker;
private volatile
Interruptible blocker;
private Object
blockerLock = new Object();
void
blockedOn(Interruptible b) {
synchronized
(blockerLock) {
blocker =
b;
}
}
public final
static int MIN_PRIORITY = 1;
public final
static int NORM_PRIORITY = 5;
public final
static int MAX_PRIORITY = 10;
private boolean
stopBeforeStart;
private Throwable
throwableFromStop;
public static
native Thread currentThread();
public static
native void yield();
public static
native void sleep(long millis) throws InterruptedException;
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 void
init(ThreadGroup g, Runnable target, String name,
long stackSize) {
if (name == null) {
throw new
NullPointerException("name cannot be null");
}
Thread parent
= currentThread();
SecurityManager security = System.getSecurityManager();
if (g == null)
{
if
(security != null) {
g =
security.getThreadGroup();
}
if (g ==
null) {
g =
parent.getThreadGroup();
}
}
g.checkAccess();
if (security
!= null) {
if
(isCCLOverridden(getClass())) {
security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
}
g.addUnstarted();
this.group =
g;
this.daemon =
parent.isDaemon();
this.priority
= parent.getPriority();
this.name =
name.toCharArray();
if (security
== null || isCCLOverridden(parent.getClass()))
this.contextClassLoader = parent.getContextClassLoader();
else
this.contextClassLoader = parent.contextClassLoader;
this.inheritedAccessControlContext = AccessController.getContext();
this.target =
target;
setPriority(priority);
if
(parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
/* Stash the
specified stack size in case the VM cares */
this.stackSize
= stackSize;
/* Set thread
ID */
tid =
nextThreadID();
}
public Thread() {
init(null,
null, "Thread-" + nextThreadNum(), 0);
}
public
Thread(Runnable target) {
init(null,
target, "Thread-" + nextThreadNum(), 0);
}
public
Thread(ThreadGroup group, Runnable target) {
init(group,
target, "Thread-" + nextThreadNum(), 0);
}
public
Thread(String name) {
init(null,
null, name, 0);
}
public
Thread(ThreadGroup group, String name) {
init(group,
null, name, 0);
}
public
Thread(Runnable target, String name) {
init(null,
target, name, 0);
}
public
Thread(ThreadGroup group, Runnable target, String name) {
init(group,
target, name, 0);
}
public
Thread(ThreadGroup group, Runnable target, String name,
long
stackSize) {
init(group,
target, name, stackSize);
}
public
synchronized void start() {
if
(threadStatus != 0)
throw new
IllegalThreadStateException();
group.threadStarting(this);
boolean failed
= true;
try {
start0();
failed =
false;
} finally {
try {
group.threadStarted(this, failed);
} catch
(Throwable ignore) {
}
}
if
(stopBeforeStart) {
stop0(throwableFromStop);
}
}
private native
void start0();
@Override
public void run()
{
if (target !=
null) {
target.run();
}
}
private void
exit() {
if (group !=
null) {
group.threadTerminated(this);
group =
null;
}
target = null;
threadLocals =
null;
inheritableThreadLocals = null;
inheritedAccessControlContext = null;
blocker =
null;
uncaughtExceptionHandler = null;
}
@Deprecated
public final void
stop() {
// If the
thread is already dead, return.
// A zero status value corresponds to
"NEW".
if
((threadStatus != 0) && !isAlive()) {
return;
}
stop1(new
ThreadDeath());
}
@Deprecated
public final
synchronized void stop(Throwable obj) {
stop1(obj);
}
private final
synchronized void stop1(Throwable th) {
SecurityManager security = System.getSecurityManager();
if (security
!= null) {
checkAccess();
if ((this
!= Thread.currentThread()) ||
(!(th
instanceof ThreadDeath))) {
security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
}
}
// A zero status
value corresponds to "NEW"
if
(threadStatus != 0) {
resume();
// Wake up thread if it was suspended; no-op otherwise
stop0(th);
} else {
// Must do
the null arg check that the VM would do with stop0
if (th ==
null) {
throw
new NullPointerException();
}
//
Remember this stop attempt for if/when start is used
stopBeforeStart = true;
throwableFromStop = th;
}
}
public void
interrupt() {
if (this !=
Thread.currentThread())
checkAccess();
synchronized
(blockerLock) {
Interruptible b = blocker;
if (b !=
null) {
interrupt0(); // Just to
set the interrupt flag
b.interrupt();
return;
}
}
interrupt0();
}
public static
boolean interrupted() {
return
currentThread().isInterrupted(true);
}
public boolean
isInterrupted() {
return
isInterrupted(false);
}
private native
boolean isInterrupted(boolean ClearInterrupted);
@Deprecated
public void
destroy() {
throw new
NoSuchMethodError();
}
public final
native boolean isAlive();
@Deprecated
public final void
suspend() {
checkAccess();
suspend0();
}
@Deprecated
public final void
resume() {
checkAccess();
resume0();
}
public final void
setPriority(int newPriority) {
ThreadGroup g;
checkAccess();
if
(newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
throw new
IllegalArgumentException();
}
if((g =
getThreadGroup()) != null) {
if
(newPriority > g.getMaxPriority()) {
newPriority = g.getMaxPriority();
}
setPriority0(priority = newPriority);
}
}
public final int
getPriority() {
return
priority;
}
public final void
setName(String name) {
checkAccess();
this.name =
name.toCharArray();
}
public final
String getName() {
return
String.valueOf(name);
}
public final
ThreadGroup getThreadGroup() {
return group;
}
public static int
activeCount() {
return
currentThread().getThreadGroup().activeCount();
}
public static int
enumerate(Thread tarray[]) {
return
currentThread().getThreadGroup().enumerate(tarray);
}
@Deprecated
public native int
countStackFrames();
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;
}
}
}
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);
}
public final void
join() throws InterruptedException {
join(0);
}
public static void
dumpStack() {
new
Exception("Stack trace").printStackTrace();
}
public final void
setDaemon(boolean on) {
checkAccess();
if (isAlive())
{
throw new
IllegalThreadStateException();
}
daemon = on;
}
public final
boolean isDaemon() {
return daemon;
}
public final void
checkAccess() {
SecurityManager security = System.getSecurityManager();
if (security
!= null) {
security.checkAccess(this);
}
}
public String
toString() {
ThreadGroup
group = getThreadGroup();
if (group !=
null) {
return
"Thread[" + getName() + "," + getPriority() + ","
+
group.getName() + "]";
} else {
return
"Thread[" + getName() + "," + getPriority() + ","
+
"" + "]";
}
}
public ClassLoader
getContextClassLoader() {
if
(contextClassLoader == null)
return
null;
SecurityManager sm = System.getSecurityManager();
if (sm !=
null) {
ClassLoader ccl = ClassLoader.getCallerClassLoader();
if (ccl !=
null && ccl != contextClassLoader &&
!contextClassLoader.isAncestor(ccl))
{
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
return
contextClassLoader;
}
public void
setContextClassLoader(ClassLoader cl) {
SecurityManager sm = System.getSecurityManager();
if (sm !=
null) {
sm.checkPermission(new
RuntimePermission("setContextClassLoader"));
}
contextClassLoader = cl;
}
public static
native boolean holdsLock(Object obj);
private static
final StackTraceElement[] EMPTY_STACK_TRACE
= new
StackTraceElement[0];
public
StackTraceElement[] getStackTrace() {
if (this !=
Thread.currentThread()) {
SecurityManager security = System.getSecurityManager();
if
(security != null) {
security.checkPermission(
SecurityConstants.GET_STACK_TRACE_PERMISSION);
}
if
(!isAlive()) {
return
EMPTY_STACK_TRACE;
}
StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[]
{this});
StackTraceElement[] stackTrace = stackTraceArray[0];
if
(stackTrace == null) {
stackTrace = EMPTY_STACK_TRACE;
}
return
stackTrace;
} else {
// Don't
need JVM help for current thread
return
(new Exception()).getStackTrace();
}
}
public static
Map<Thread, StackTraceElement[]> getAllStackTraces() {
SecurityManager security = System.getSecurityManager();
if (security
!= null) {
security.checkPermission(
SecurityConstants.GET_STACK_TRACE_PERMISSION);
security.checkPermission(
SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
}
// Get a
snapshot of the list of all threads
Thread[]
threads = getThreads();
StackTraceElement[][] traces = dumpThreads(threads);
Map<Thread,
StackTraceElement[]> m
= new
HashMap<Thread, StackTraceElement[]>(threads.length);
for (int i =
0; i < threads.length; i++) {
StackTraceElement[] stackTrace = traces[i];
if
(stackTrace != null) {
m.put(threads[i], stackTrace);
}
// else
terminated so we don't put it in the map
}
return m;
}
private static
final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
new
RuntimePermission("enableContextClassLoaderOverride");
private static
class Caches {
static final
ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
new
ConcurrentHashMap<WeakClassKey,Boolean>();
static final
ReferenceQueue<Class<?>> subclassAuditsQueue =
new
ReferenceQueue<Class<?>>();
}
private static
boolean isCCLOverridden(Class cl) {
if (cl ==
Thread.class)
return false;
processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
WeakClassKey
key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
Boolean result
= Caches.subclassAudits.get(key);
if (result ==
null) {
result =
Boolean.valueOf(auditSubclass(cl));
Caches.subclassAudits.putIfAbsent(key, result);
}
return
result.booleanValue();
}
private static
boolean auditSubclass(final Class subcl) {
Boolean result
= AccessController.doPrivileged(
new
PrivilegedAction<Boolean>() {
public
Boolean run() {
for (Class cl = subcl;
cl != Thread.class;
cl = cl.getSuperclass())
{
try {
cl.getDeclaredMethod("getContextClassLoader", new Class[0]);
return Boolean.TRUE;
} catch (NoSuchMethodException ex) {
}
try {
Class[] params = {ClassLoader.class};
cl.getDeclaredMethod("setContextClassLoader", params);
return Boolean.TRUE;
} catch (NoSuchMethodException ex) {
}
}
return Boolean.FALSE;
}
}
);
return
result.booleanValue();
}
private native static StackTraceElement[][]
dumpThreads(Thread[] threads);
private native
static Thread[] getThreads();
public long
getId() {
return tid;
}
public enum State
{
/**
* Thread
state for a thread which has not yet started.
*/
NEW,
/**
* Thread
state for a runnable thread. A thread in
the runnable
* state is
executing in the Java virtual machine but it may
* be waiting
for other resources from the operating system
* such as
processor.
*/
RUNNABLE,
/**
* Thread
state for a thread blocked waiting for a monitor lock.
* A thread in
the blocked state is waiting for a monitor lock
* to enter a
synchronized block/method or
* reenter a
synchronized block/method after calling
* {@link
Object#wait() Object.wait}.
*/
BLOCKED,
/**
* Thread
state for a waiting thread.
* A thread is
in the waiting state due to calling one of the
* following
methods:
* <ul>
* <li>{@link Object#wait() Object.wait}
with no timeout</li>
*
<li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park()
LockSupport.park}</li>
* </ul>
*
* <p>A
thread in the waiting state is waiting for another thread to
* perform a
particular action.
*
* For
example, a thread that has called <tt>Object.wait()</tt>
* on an
object is waiting for another thread to call
*
<tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt>
on
* that
object. A thread that has called <tt>Thread.join()</tt>
* is waiting
for a specified thread to terminate.
*/
WAITING,
/**
* Thread
state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due
to calling one of
* the
following methods with a specified positive waiting time:
* <ul>
* <li>{@link #sleep
Thread.sleep}</li>
* <li>{@link Object#wait(long)
Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join}
with timeout</li>
* <li>{@link LockSupport#parkNanos
LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil
LockSupport.parkUntil}</li>
* </ul>
*/
TIMED_WAITING,
/**
* Thread
state for a terminated thread.
* The thread
has completed execution.
*/
TERMINATED;
}
/**
* Returns the
state of this thread.
* This method is
designed for use in monitoring of the system state,
* not for
synchronization control.
*
* @return this
thread's state.
* @since 1.5
*/
public State
getState() {
// get current
thread state
return
sun.misc.VM.toThreadState(threadStatus);
}
public interface
UncaughtExceptionHandler {
void uncaughtException(Thread t, Throwable
e);
}
// null unless
explicitly set
private volatile
UncaughtExceptionHandler uncaughtExceptionHandler;
// null unless
explicitly set
private static
volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
public static void
setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
SecurityManager sm = System.getSecurityManager();
if (sm !=
null) {
sm.checkPermission(
new
RuntimePermission("setDefaultUncaughtExceptionHandler")
);
}
defaultUncaughtExceptionHandler = eh;
}
public static
UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){
return
defaultUncaughtExceptionHandler;
}
public UncaughtExceptionHandler
getUncaughtExceptionHandler() {
return
uncaughtExceptionHandler != null ?
uncaughtExceptionHandler : group;
}
public void
setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
checkAccess();
uncaughtExceptionHandler = eh;
}
private void
dispatchUncaughtException(Throwable e) {
getUncaughtExceptionHandler().uncaughtException(this, e);
}
static void
processQueue(ReferenceQueue<Class<?>> queue,
ConcurrentMap<? extends
WeakReference<Class<?>>, ?> map)
{
Reference<?
extends Class<?>> ref;
while((ref =
queue.poll()) != null) {
map.remove(ref);
}
}
static class
WeakClassKey extends WeakReference<Class<?>> {
private final
int hash;
WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>>
refQueue) {
super(cl,
refQueue);
hash =
System.identityHashCode(cl);
}
@Override
public int
hashCode() {
return
hash;
}
@Override
public boolean
equals(Object obj) {
if (obj ==
this)
return true;
if (obj
instanceof WeakClassKey) {
Object
referent = get();
return
(referent != null) &&
(referent == ((WeakClassKey) obj).get());
} else {
return
false;
}
}
}
}
No comments:
Post a Comment