java 多线程 Thread 类 详解翻译

/*

  • Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.

  • ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
    *
    */

package java.lang;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.AccessControlContext;
import java.security.PrivilegedAction;
import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.LockSupport;
import sun.nio.ch.Interruptible;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;

/**
* 线程是程序中的执行器. java 虚拟机允许多线程并发执行
*
* 每个线程都有优先级. 高优先级的线程先于低优先级执行.
* 每个线程都可以被标记为或者不标记为守护线程. 如果一个线程被另外一个线程创建
* 这个新线程被初始化的优先级和其创建线程相同
* 是否为守护线程也与其创建线程相同
* 当虚拟机启动的时候,这里有一个单一的
* 非守护的线程 ( 通常其典型方法为 main 的设计好的类中)
* java 虚拟机会持续运行线程,直到如下发生:
*
* 退出方法在运行态呗调用,并且安全机制允许退出
* 所有的非守护线程在调用 run 方法后抛出异常且死亡
*


* 有 2 中方式来创建要给执行线程. 其一是继承 Thread 类. 并重写该类的 run 方法
* 这个线程实例就会被分配和启动. 例如,一个线程计算 素数,该数大于保存的数
* class PrimeThread extends Thread {
* long minPrime;
* PrimeThread(long minPrime) {
* this.minPrime = minPrime;
* }
*
* public void run() {
* // compute primes larger than minPrime
*  . . .
* }
* }
* 下面为创建启动线程方法
* PrimeThread p = new PrimeThread(143);
* p.start();
* 另一个方式是创建实现 Runnable 接口的类.
* 例子如下
*
* class PrimeRun implements Runnable {
* long minPrime;
* PrimeRun(long minPrime) {
* this.minPrime = minPrime;
* }
*
* public void run() {
* // compute primes larger than minPrime
*  . . .
* }
* }
* 启动方式
* PrimeRun p = new PrimeRun(143);
* new Thread(p).start();
* 每个线程有自己被定义的名字. 如果多个线程名相互重复
* 先创创建时会生成一个新名字
*
*
* @author unascribed
* @see Runnable
* @see Runtime#exit(int)
* @see #run()
* @see #stop()
* @since JDK1.0
/
public
class Thread implements Runnable {
/
Make sure registerNatives is the first thing does. /
private static native void registerNatives();
/

这是一个本地方法,registerNatives

 那么可以使用 registerNatives 方式来注册本地函数,这样就可以随意命名函数。而且认为经过 registerNatives 往 JVM 中注册的函数在执行时会更加高效,因为函数的查找更快了。

有两种方式可以实现本地方法注册:

### 1、Java 中静态块
  • 在 Java 类中声明一个registerNatives静态方法。
  • 在本地代码中定义一个Java_<fully qualified class name>_registerNatives函数。
  • 在调用其他本地函数前要先调用registerNatives方法。

比如对于 Object 类,在类中进行如下操作:

private static native void registerNatives();
static {
registerNatives();
}

本地中通过registerNatives将指定的本地方法绑定到指定函数,比如这里将hashCodeclone本地方法绑定到JVM_IHashCodeJVM_IHashCode函数。

static JNINativeMethod methods[] = {
{“hashCode”, “()I”, (void *)&JVM_IHashCode},
{“clone”, “()Ljava/lang/Object;”, (void *)&JVM_Clone},
};

JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls,
methods, sizeof(methods)/sizeof(methods[0]));
}

2、使用 JNI_OnLoad

JNI_OnLoad函数在 JVM 执行System.loadLibrary方法时被调用,所以可以在该方法中调用RegisterNatives函数注册本地函数。通过该种方式注册本地方法则无需在 Java 类中声明RegisterNatives本地方法来注册了。

static JNINativeMethod methods[] = {
{“hashCode”, “()I”, (void *)&JVM_IHashCode},
{“clone”, “()Ljava/lang/Object;”, (void *)&JVM_Clone},
};

int JNI_OnLoad(JavaVM* vm, void* reserved)
{

if ((*env)->RegisterNatives(env, cls,
methods, sizeof(methods)/sizeof(methods[0])) < 0)
{
return JNI_ERR;
}

}

registerNatives 干了什么

定义了 JNINativeMethod 结构体用于声明方法和函数,如下,name 表示 Java 的本地方法名,signature 表示方法的签名,fnPtr 表示函数指针。

typedef struct {
char *name;
char *signature;
void *fnPtr;
} JNINativeMethod;

主要要看(*env)->RegisterNatives这个函数,

JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls,
methods, sizeof(methods)/sizeof(methods[0]));
}

该方法的声明在一个JNINativeInterface_结构体中,该结构体包含了 JNI 的所有接口函数声明,JVM 中定义了结构体变量jni_NativeInterface来使用,这里只列出RegisterNatives函数的声明,其他函数省略。

struct JNINativeInterface_ {

jint (JNICALL *RegisterNatives) (JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint nMethods);

}

struct JNINativeInterface_ jni_NativeInterface = {

jni_RegisterNatives,

}

在看jni_RegisterNatives函数的实现前先了解JNI_ENTRYJNI_END宏,这两个宏将共同的部分都抽离出来了。其中JNI_END比较简单,就两个结束大括号。

#define JNI_ENTRY(result_type, header) JNI_ENTRY_NO_PRESERVE(result_type, header) WeakPreserveExceptionMark __wem(thread);

#define JNI_END } }

JNI_ENTRY主要逻辑:

  • 获取当前执行线程 JavaThread 指针对象。
  • 创建 ThreadInVMfromNative 对象。
  • TRACE_CALL ,这里什么都不干。
  • 创建 HandleMarkCleaner 对象。
  • 将 thread 赋值给 Exceptions 中的 THREAD。
  • 校验栈对齐。
  • 创建 WeakPreserveExceptionMark 对象。

#define JNI_ENTRY_NO_PRESERVE(result_type, header)
extern “C” {
result_type JNICALL header {
JavaThread* thread=JavaThread::thread_from_jni_environment(env);
assert(!VerifyJNIEnvThread || (thread == Thread::current()), “JNIEnv is only valid in same thread”);
ThreadInVMfromNative __tiv(thread);
debug_only(VMNativeEntryWrapper __vew;)
VM_ENTRY_BASE(result_type, header, thread)

#define VM_ENTRY_BASE(result_type, header, thread)
TRACE_CALL(result_type, header)
HandleMarkCleaner __hm(thread);
Thread* THREAD = thread;
os::verify_stack_alignment();

现在看jni_RegisterNatives函数具体的实现,逻辑为:

  • JNIWrapper 用于 debug。
  • HOTSPOT_JNI_REGISTERNATIVES_ENTRY 和 DT_RETURN_MARK 都用于 dtrace。
  • 创建 KlassHandle 对象。
  • 开始遍历方法数组,获取对应的方法名、方法签名和方法长度等信息。
  • 尝试在符号常量池中查找是否已经存在对应的方法名和方法签名,如果找不到则要抛异常,因为正常情况加载 Java 类时已经添加到常量池中了。
  • 调用register_native函数注册。

JNI_ENTRY(jint, jni_RegisterNatives(JNIEnv *env, jclass clazz,
const JNINativeMethod *methods,
jint nMethods))
JNIWrapper(“RegisterNatives”);
HOTSPOT_JNI_REGISTERNATIVES_ENTRY(env, clazz, (void *) methods, nMethods);
jint ret = 0;
DT_RETURN_MARK(RegisterNatives, jint, (const jint&)ret);

KlassHandle h_k(thread, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));

for (int index = 0; index < nMethods; index++) {
const char* meth_name = methods[index].name;
const char* meth_sig = methods[index].signature;
int meth_name_len = (int)strlen(meth_name);

TempNewSymbol  name = SymbolTable::probe(meth_name, meth_name_len);
TempNewSymbol  signature = SymbolTable::probe(meth_sig, (int)strlen(meth_sig));

if (name == NULL || signature == NULL) {
  ResourceMark rm;
  stringStream st;
  st.print("Method %s.%s%s not found", h_k()->external_name(), meth_name, meth_sig);
  THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), -1);
}

bool res = register_native(h_k, name, signature,
                           (address) methods[index].fnPtr, THREAD);
if (!res) {
  ret = -1;
  break;
}

}
return ret;
JNI_END

register_native函数逻辑如下:

  • 到对应 Klass 对象中查找指定方法,如果不存在则抛异常。
  • 方法如果不是声明为 native,则先尝试查找被添加了前缀的本地方法,这个是因为可能在 JVM TI agent 中设置某些 native 方法的前缀,如果还是为空则最终抛出异常。
  • 调用最重要的set_native_function函数,将 C++ 的函数绑定到该 Method 对象中。
  • 如果函数指针为空,则调用clear_native_function清理本地方法对象。

static bool register_native(KlassHandle k, Symbol* name, Symbol* signature, address entry, TRAPS) {
Method* method = k()->lookup_method(name, signature);
if (method == NULL) {
ResourceMark rm;
stringStream st;
st.print(“Method %s name or signature does not match”,
Method::name_and_sig_as_C_string(k(), name, signature));
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
}
if (!method->is_native()) {
method = find_prefixed_native(k, name, signature, THREAD);
if (method == NULL) {
ResourceMark rm;
stringStream st;
st.print(“Method %s is not declared as native”,
Method::name_and_sig_as_C_string(k(), name, signature));
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
}
}

if (entry != NULL) {
method->set_native_function(entry,
Method::native_bind_event_is_interesting);
} else {
method->clear_native_function();
}
if (PrintJNIResolving) {
ResourceMark rm(THREAD);
tty->print_cr(“[Registering JNI native method %s.%s]”,
method->method_holder()->external_name(),
method->name()->as_C_string());
}
return true;
}

set_native_function函数逻辑为:

  • 通过native_function_addr函数获取本地函数地址,这个函数直接return (address*) (this+1);,可以看到它是直接将 Method 对象的地址 +1 作为本地函数地址的。能够这样操作是因为在创建 Method 对象时会判断是否为 native 方法,如果是则会额外留两个地址位置,分别用于本地函数地址和方法签名。
  • 判断本地函数地址是否已经等于函数指针,是的话说明已经绑定,直接返回,否则继续往下。
  • 如果 Jvmti 设置了传播绑定本地方法事件则发送事件。
  • 将函数指针赋给本地函数地址。
  • GCC 获取编译的函数代码。

void Method::set_native_function(address function, bool post_event_flag) {
assert(function != NULL, “use clear_native_function to unregister natives”);
assert(!is_method_handle_intrinsic() || function == SharedRuntime::native_method_throw_unsatisfied_link_error_entry(), "");
address* native_function = native_function_addr();

address current = *native_function;
if (current == function) return;
if (post_event_flag && JvmtiExport::should_post_native_method_bind() &&
function != NULL) {
assert(function !=
SharedRuntime::native_method_throw_unsatisfied_link_error_entry(),
“post_event_flag mis-match”);
JvmtiExport::post_native_method_bind(this, &function);
}
native_function = function;
CompiledMethod
nm = code();
if (nm != NULL) {
nm->make_not_entrant();
}
}

*/
static {
registerNatives();
}

private volatile String name;
private int            priority;
private Thread         threadQ;
private long           eetop;
//

/*是否为单步骤线程. */
private boolean     single_step;

/* 是否为守护线程. */
private boolean     daemon = false;

/* JVM 状态*/
private boolean     stillborn = false;

/* 执行的target. */
private Runnable target;

/* 该线程的线程Group */
private ThreadGroup group;

/*  该线程环境的ClassLoader */
private ClassLoader contextClassLoader;

/* 该线程继承的 AccessControlContext */
private AccessControlContext inheritedAccessControlContext;

/* 自动命名的匿名线程. */
private static int threadInitNumber;
private static synchronized int nextThreadNum() {
    return threadInitNumber++;
}

/* 线程持有的ThreadLocal变量. 这个map被
 * ThreadLocal class 持有. */
ThreadLocal.ThreadLocalMap threadLocals = null;

/*
 * 该线程预持有的可继承的ThreadLocal 变量  这个map
 * 被 InheritableThreadLocal class 持有.
 */
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;

/*
 * 该线程所需栈的大小,如果为0,表示该线程没有定义栈的大小
 *  这依赖于 VM 去确定这个数字,有些VM会忽略它
 */
private long stackSize;

/*
 * JVM私有状态,线程死亡jvm也留存.
 */
private long nativeParkEventPointer;

/*
 * 线程id
 */
private long tid;

/* 生成的 thread ID */
private static long threadSeqNumber;

/* Java thread 给工具类查询的状态,
 * 初始化表示这个类至今是否启动
 */

private volatile int threadStatus = 0;


private static synchronized long nextThreadID() {
    return ++threadSeqNumber;
}

/**
 * 被这个类调用
 * java.util.concurrent.locks.LockSupport.park.
 * Set by (private) java.util.concurrent.locks.LockSupport.setBlocker
 * Accessed using java.util.concurrent.locks.LockSupport.getBlocker
 */
volatile Object parkBlocker;

/* 这个对象是线程持有的可中断的io操作 
 *  这个调用状态是
 * 设置了该线程的中断状态之后
 */
private volatile Interruptible blocker;
private final Object blockerLock = new Object();

/*设置阻止程序字段; 通过 sun.misc.SharedSecrets 在java.nio 中调用
 */
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;

/**
 * 返回当前线程的应用,这个一个java虚拟机的方法
 *
 * @return  the currently executing thread.
 */
public static native Thread currentThread();

/**
 * 向调度程序提示当前线程愿意被调度。调度程序可以忽略此提示。
 *
 * 通知调度是一种尝试,来处境不同线程之间的更好的运行 
 *  这个用法需要结合具体的使用场景和分析测试来使用
 *
 * 该方法极少被用到. 在测试和调试中这个方法比较有效,可以重现bug和竞争条件
 *  他在并发控制中也被用到
 * 比如
 * {@link java.util.concurrent.locks} 包.
 */
public static native void yield();

/**
 * 使当前进程休眠多少毫秒, 受控于系统时间 线程不会丢失任何监视器的所有权。
 *
 * @param  millis
 *         the length of time to sleep in milliseconds
 *
 * @throws  IllegalArgumentException
 *          if the value of {@code millis} is negative
 *
 * @throws  InterruptedException
 *          if any thread has interrupted the current thread. The
 *          <i>interrupted status</i> of the current thread is
 *          cleared when this exception is thrown.
 */
public static native void sleep(long millis) throws InterruptedException;

/**
 * 使当前执行的线程休眠(暂时停止执行)指定的毫秒数加上指定的纳秒数,取决于系统计时器和调度程序的精度和准确性。线程不会丢失任何监视器的所有权。
 *
 * @param  millis
 *         the length of time to sleep in milliseconds
 *
 * @param  nanos
 *         {@code 0-999999} additional nanoseconds to sleep
 *
 * @throws  IllegalArgumentException
 *          if the value of {@code millis} is negative, or the value of
 *          {@code nanos} is not in the range {@code 0-999999}
 *
 * @throws  InterruptedException
 *          if any thread has interrupted the current thread. The
 *          <i>interrupted status</i> of the current thread is
 *          cleared when this exception is thrown.
 */
public static void sleep(long millis, int nanos)
throws InterruptedException {
    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }

    if (nanos < 0 || nanos > 999999) {
        throw new IllegalArgumentException(
                            "nanosecond timeout value out of range");
    }

    if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
        millis++;
    }

    sleep(millis);
}

/**
 * 用 AccessControlContext初始化线程
 * @see #init(ThreadGroup,Runnable,String,long,AccessControlContext,boolean)
 */
private void init(ThreadGroup g, Runnable target, String name,
                  long stackSize) {
    init(g, target, name, stackSize, null, true);
}

/**
 * 初始化线程.
 *
 * @param g 线程组
 * @param  run() 调用的目标
 * @param 线程名
 * @param stackSize 线程stacksize
 * @param acc 线程继承的 AccessControlContext to inherit, 如果为空
 *            AccessController.getContext() 
 * @param inheritThreadLocals 线程初始化变量
 */
private void init(ThreadGroup g, Runnable target, String name,
                  long stackSize, AccessControlContext acc,
                  boolean inheritThreadLocals) {
    if (name == null) {
        throw new NullPointerException("name cannot be null");
    }

    this.name = name;

    Thread parent = currentThread();
    SecurityManager security = System.getSecurityManager();
    if (g == null) {
        /* Determine if it's an applet or not */

        /* If there is a security manager, ask the security manager
           what to do. */
        if (security != null) {
            g = security.getThreadGroup();
        }

        /* If the security doesn't have a strong opinion of the matter
           use the parent thread group. */
        if (g == null) {
            g = parent.getThreadGroup();
        }
    }

    /* 检查线程组权限. */
    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();
    if (security == null || isCCLOverridden(parent.getClass()))
        this.contextClassLoader = parent.getContextClassLoader();
    else
        this.contextClassLoader = parent.contextClassLoader;
    this.inheritedAccessControlContext =
            acc != null ? acc : AccessController.getContext();
    this.target = target;
    setPriority(priority);
    if (inheritThreadLocals && 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();
}

/**
 * 抛出 CloneNotSupportedException 当线程不能被clone
 * 新建线程替代.
 *
 * @throws  CloneNotSupportedException
 *          always
 */
@Override
protected Object clone() throws CloneNotSupportedException {
    throw new CloneNotSupportedException();
}

/**
 * 分配新线程对象
 */
public Thread() {
    init(null, null, "Thread-" + nextThreadNum(), 0);
}

/**
 * 分配新线程,用runnable接口
 * @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);
}

/**
 * 用给定的 AccessControlContext 创建新线程.
 * This is not a public constructor.
 */
Thread(Runnable target, AccessControlContext acc) {
    init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
}

/**
 * 创建新线程,给定ThreadGroup
 *
 * @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);
}

/**
 * 创建新线程给定线程名
 *
 * @param   name
 *          the name of the new thread
 */
public Thread(String name) {
    init(null, null, name, 0);
}

/**
 * 创建新线程给定Threadgroup和线程名
 *
 * @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);
}

/**
 * 给定runnable和线程名
 *
 * @param  target
 *         the object whose {@code run} method is invoked when this thread
 *         is started. If {@code null}, this thread's run method is invoked.
 *
 * @param  name
 *         the name of the new thread
 */
public Thread(Runnable target, String name) {
    init(null, target, name, 0);
}

/**
 * Allocates a new {@code Thread} object so that it has {@code target}
 * as its run object, has the specified {@code name} as its name,
 * and belongs to the thread group referred to by {@code group}.
 *
 * <p>If there is a security manager, its
 * {@link SecurityManager#checkAccess(ThreadGroup) checkAccess}
 * method is invoked with the ThreadGroup as its argument.
 *
 * <p>In addition, its {@code checkPermission} method is invoked with
 * the {@code RuntimePermission("enableContextClassLoaderOverride")}
 * permission when invoked directly or indirectly by the constructor
 * of a subclass which overrides the {@code getContextClassLoader}
 * or {@code setContextClassLoader} methods.
 *
 * <p>The priority of the newly created thread is set equal to the
 * priority of the thread creating it, that is, the currently running
 * thread. The method {@linkplain #setPriority setPriority} may be
 * used to change the priority to a new value.
 *
 * <p>The newly created thread is initially marked as being a daemon
 * thread if and only if the thread creating it is currently marked
 * as a daemon thread. The method {@linkplain #setDaemon setDaemon}
 * may be used to change whether or not a thread is a daemon.
 *
 * @param  group
 *         the thread group. If {@code null} and there is a security
 *         manager, the group is determined by {@linkplain
 *         SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
 *         If there is not a security manager or {@code
 *         SecurityManager.getThreadGroup()} returns {@code null}, the group
 *         is set to the current thread's thread group.
 *
 * @param  target
 *         the object whose {@code run} method is invoked when this thread
 *         is started. If {@code null}, this thread's run method is invoked.
 *
 * @param  name
 *         the name of the new thread
 *
 * @throws  SecurityException
 *          if the current thread cannot create a thread in the specified
 *          thread group or cannot override the context class loader methods.
 */
public Thread(ThreadGroup group, Runnable target, String name) {
    init(group, target, name, 0);
}

/**
 * Allocates a new {@code Thread} object so that it has {@code target}
 * as its run object, has the specified {@code name} as its name,
 * and belongs to the thread group referred to by {@code group}, and has
 * the specified <i>stack size</i>.
 *
 * <p>This constructor is identical to {@link
 * #Thread(ThreadGroup,Runnable,String)} with the exception of the fact
 * that it allows the thread stack size to be specified.  The stack size
 * is the approximate number of bytes of address space that the virtual
 * machine is to allocate for this thread's stack.  <b>The effect of the
 * {@code stackSize} parameter, if any, is highly platform dependent.</b>
 *
 * <p>On some platforms, specifying a higher value for the
 * {@code stackSize} parameter may allow a thread to achieve greater
 * recursion depth before throwing a {@link StackOverflowError}.
 * Similarly, specifying a lower value may allow a greater number of
 * threads to exist concurrently without throwing an {@link
 * OutOfMemoryError} (or other internal error).  The details of
 * the relationship between the value of the <tt>stackSize</tt> parameter
 * and the maximum recursion depth and concurrency level are
 * platform-dependent.  <b>On some platforms, the value of the
 * {@code stackSize} parameter may have no effect whatsoever.</b>
 *
 * <p>The virtual machine is free to treat the {@code stackSize}
 * parameter as a suggestion.  If the specified value is unreasonably low
 * for the platform, the virtual machine may instead use some
 * platform-specific minimum value; if the specified value is unreasonably
 * high, the virtual machine may instead use some platform-specific
 * maximum.  Likewise, the virtual machine is free to round the specified
 * value up or down as it sees fit (or to ignore it completely).
 *
 * <p>Specifying a value of zero for the {@code stackSize} parameter will
 * cause this constructor to behave exactly like the
 * {@code Thread(ThreadGroup, Runnable, String)} constructor.
 *
 * <p><i>Due to the platform-dependent nature of the behavior of this
 * constructor, extreme care should be exercised in its use.
 * The thread stack size necessary to perform a given computation will
 * likely vary from one JRE implementation to another.  In light of this
 * variation, careful tuning of the stack size parameter may be required,
 * and the tuning may need to be repeated for each JRE implementation on
 * which an application is to run.</i>
 *
 * <p>Implementation note: Java platform implementers are encouraged to
 * document their implementation's behavior with respect to the
 * {@code stackSize} parameter.
 *
 *
 * @param  group
 *         the thread group. If {@code null} and there is a security
 *         manager, the group is determined by {@linkplain
 *         SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
 *         If there is not a security manager or {@code
 *         SecurityManager.getThreadGroup()} returns {@code null}, the group
 *         is set to the current thread's thread group.
 *
 * @param  target
 *         the object whose {@code run} method is invoked when this thread
 *         is started. If {@code null}, this thread's run method is invoked.
 *
 * @param  name
 *         the name of the new thread
 *
 * @param  stackSize
 *         the desired stack size for the new thread, or zero to indicate
 *         that this parameter is to be ignored.
 *
 * @throws  SecurityException
 *          if the current thread cannot create a thread in the specified
 *          thread group
 *
 * @since 1.4
 */
public Thread(ThreadGroup group, Runnable target, String name,
              long stackSize) {
    init(group, target, name, stackSize);
}

/**
 * 启动执行; 虚拟机native方法
 * <p>
 * The result is that two threads are running concurrently: the
 * current thread (which returns from the call to the
 * <code>start</code> method) and the other thread (which executes its
 * <code>run</code> method).
 * <p>
 * It is never legal to start a thread more than once.
 * In particular, a thread may not be restarted once it has completed
 * execution.
 *
 * @exception  IllegalThreadStateException  if the thread was already
 *               started.
 * @see        #run()
 * @see        #stop()
 */
public synchronized void start() {
    /**
     * This method is not invoked for the main method thread or "system"
     * group threads created/set up by the VM. Any new functionality added
     * to this method in the future may have to also be added to the VM.
     *
     * A zero status value corresponds to state "NEW".
     */
    if (threadStatus != 0)
        throw new IllegalThreadStateException();

    /* Notify the group that this thread is about to be started
     * so that it can be added to the group's list of threads
     * and the group's unstarted count can be decremented. */
    group.add(this);

    boolean started = false;
    try {
        start0();
        started = true;
    } finally {
        try {
            if (!started) {
                group.threadStartFailed(this);
            }
        } catch (Throwable ignore) {
            /* do nothing. If start0 threw a Throwable then
              it will be passed up the call stack */
        }
    }
}

private native void start0();

/**
 * If this thread was constructed using a separate
 * <code>Runnable</code> run object, then that
 * <code>Runnable</code> object's <code>run</code> method is called;
 * otherwise, this method does nothing and returns.
 * <p>
 * Subclasses of <code>Thread</code> should override this method.
 *
 * @see     #start()
 * @see     #stop()
 * @see     #Thread(ThreadGroup, Runnable, String)
 */
@Override
public void run() {
    if (target != null) {
        target.run();
    }
}

/**
 * 系统调用,清除内容,在线程退出前
 */
private void exit() {
    if (group != null) {
        group.threadTerminated(this);
        group = null;
    }
    /* Aggressively null out all reference fields: see bug 4006245 */
    target = null;
    /* Speed the release of some of these resources */
    threadLocals = null;
    inheritableThreadLocals = null;
    inheritedAccessControlContext = null;
    blocker = null;
    uncaughtExceptionHandler = null;
}

/**
 * thread 停止执行.
 * <p>
 * If there is a security manager installed, its <code>checkAccess</code>
 * method is called with <code>this</code>
 * as its argument. This may result in a
 * <code>SecurityException</code> being raised (in the current thread).
 * <p>
 * If this thread is different from the current thread (that is, the current
 * thread is trying to stop a thread other than itself), the
 * security manager's <code>checkPermission</code> method (with a
 * <code>RuntimePermission("stopThread")</code> argument) is called in
 * addition.
 * Again, this may result in throwing a
 * <code>SecurityException</code> (in the current thread).
 * <p>
 * The thread represented by this thread is forced to stop whatever
 * it is doing abnormally and to throw a newly created
 * <code>ThreadDeath</code> object as an exception.
 * <p>
 * It is permitted to stop a thread that has not yet been started.
 * If the thread is eventually started, it immediately terminates.
 * <p>
 * An application should not normally try to catch
 * <code>ThreadDeath</code> unless it must do some extraordinary
 * cleanup operation (note that the throwing of
 * <code>ThreadDeath</code> causes <code>finally</code> clauses of
 * <code>try</code> statements to be executed before the thread
 * officially dies).  If a <code>catch</code> clause catches a
 * <code>ThreadDeath</code> object, it is important to rethrow the
 * object so that the thread actually dies.
 * <p>
 * The top-level error handler that reacts to otherwise uncaught
 * exceptions does not print out a message or otherwise notify the
 * application if the uncaught exception is an instance of
 * <code>ThreadDeath</code>.
 *
 * @exception  SecurityException  if the current thread cannot
 *               modify this thread.
 * @see        #interrupt()
 * @see        #checkAccess()
 * @see        #run()
 * @see        #start()
 * @see        ThreadDeath
 * @see        ThreadGroup#uncaughtException(Thread,Throwable)
 * @see        SecurityManager#checkAccess(Thread)
 * @see        SecurityManager#checkPermission
 * @deprecated This method is inherently unsafe.  Stopping a thread with
 *       Thread.stop causes it to unlock all of the monitors that it
 *       has locked (as a natural consequence of the unchecked
 *       <code>ThreadDeath</code> exception propagating up the stack).  If
 *       any of the objects previously protected by these monitors were in
 *       an inconsistent state, the damaged objects become visible to
 *       other threads, potentially resulting in arbitrary behavior.  Many
 *       uses of <code>stop</code> should be replaced by code that simply
 *       modifies some variable to indicate that the target thread should
 *       stop running.  The target thread should check this variable
 *       regularly, and return from its run method in an orderly fashion
 *       if the variable indicates that it is to stop running.  If the
 *       target thread waits for long periods (on a condition variable,
 *       for example), the <code>interrupt</code> method should be used to
 *       interrupt the wait.
 *       For more information, see
 *       <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
 *       are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
 */
@Deprecated
public final void stop() {
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        checkAccess();
        if (this != Thread.currentThread()) {
            security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
        }
    }
    // A zero status value corresponds to "NEW", it can't change to
    // not-NEW because we hold the lock.
    if (threadStatus != 0) {
        resume(); // Wake up thread if it was suspended; no-op otherwise
    }

    // The VM can handle all thread states
    stop0(new ThreadDeath());
}

/**
 * 抛出异常的停止执行.
 *
 * @param obj ignored
 *
 * @deprecated This method was originally designed to force a thread to stop
 *        and throw a given {@code Throwable} as an exception. It was
 *        inherently unsafe (see {@link #stop()} for details), and furthermore
 *        could be used to generate exceptions that the target thread was
 *        not prepared to handle.
 *        For more information, see
 *        <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
 *        are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
 */
@Deprecated
public final synchronized void stop(Throwable obj) {
    throw new UnsupportedOperationException();
}

/**
 * 中断线程.
 *
 * <p> Unless the current thread is interrupting itself, which is
 * always permitted, the {@link #checkAccess() checkAccess} method
 * of this thread is invoked, which may cause a {@link
 * SecurityException} to be thrown.
 *
 * <p> If this thread is blocked in an invocation of the {@link
 * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link
 * Object#wait(long, int) wait(long, int)} methods of the {@link Object}
 * class, or of the {@link #join()}, {@link #join(long)}, {@link
 * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)},
 * methods of this class, then its interrupt status will be cleared and it
 * will receive an {@link InterruptedException}.
 *
 * <p> If this thread is blocked in an I/O operation upon an {@link
 * java.nio.channels.InterruptibleChannel 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}.
 *
 * <p> If this thread is blocked in a {@link java.nio.channels.Selector}
 * then the thread's interrupt status will be set and it will return
 * immediately from the selection operation, possibly with a non-zero
 * value, just as if the selector's {@link
 * java.nio.channels.Selector#wakeup wakeup} method were invoked.
 *
 * <p> If none of the previous conditions hold then this thread's interrupt
 * status will be set. </p>
 *
 * <p> Interrupting a thread that is not alive need not have any effect.
 *
 * @throws  SecurityException
 *          if the current thread cannot modify this thread
 *
 * @revised 6.0
 * @spec JSR-51
 */
public void interrupt() {
    if (this != Thread.currentThread())
        checkAccess();

    synchronized (blockerLock) {
        Interruptible b = blocker;
        if (b != null) {
            interrupt0();           // Just to set the interrupt flag
            b.interrupt(this);
            return;
        }
    }
    interrupt0();
}

/**
 * 线程中断
 * Tests whether the current thread has been interrupted.  The
 * <i>interrupted status</i> of the thread is cleared by this method.  In
 * other words, if this method were to be called twice in succession, the
 * second call would return false (unless the current thread were
 * interrupted again, after the first call had cleared its interrupted
 * status and before the second call had examined it).
 *
 * <p>A thread interruption ignored because a thread was not alive
 * at the time of the interrupt will be reflected by this method
 * returning false.
 *
 * @return  <code>true</code> if the current thread has been interrupted;
 *          <code>false</code> otherwise.
 * @see #isInterrupted()
 * @revised 6.0
 */
public static boolean interrupted() {
    return currentThread().isInterrupted(true);
}

/**
 * Tests whether this thread has been interrupted.  The <i>interrupted
 * status</i> of the thread is unaffected by this method.
 *
 * <p>A thread interruption ignored because a thread was not alive
 * at the time of the interrupt will be reflected by this method
 * returning false.
 *
 * @return  <code>true</code> if this thread has been interrupted;
 *          <code>false</code> otherwise.
 * @see     #interrupted()
 * @revised 6.0
 */
public boolean isInterrupted() {
    return isInterrupted(false);
}

/**
 * 销毁线程
 * Tests if some Thread has been interrupted.  The interrupted state
 * is reset or not based on the value of ClearInterrupted that is
 * passed.
 */
private native boolean isInterrupted(boolean ClearInterrupted);

/**
 * Throws {@link NoSuchMethodError}.
 *
 * @deprecated This method was originally designed to destroy this
 *     thread without any cleanup. Any monitors it held would have
 *     remained locked. However, the method was never implemented.
 *     If if were to be implemented, it would be deadlock-prone in
 *     much the manner of {@link #suspend}. If the target thread held
 *     a lock protecting a critical system resource when it was
 *     destroyed, no thread could ever access this resource again.
 *     If another thread ever attempted to lock this resource, deadlock
 *     would result. Such deadlocks typically manifest themselves as
 *     "frozen" processes. For more information, see
 *     <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">
 *     Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
 * @throws NoSuchMethodError always
 */
@Deprecated
public void destroy() {
    throw new NoSuchMethodError();
}

/**
 * 线程是否存活
 *
 * @return  <code>true</code> if this thread is alive;
 *          <code>false</code> otherwise.
 */
public final native boolean isAlive();

/**
 * 挂起此线程
 * <p>
 * First, the <code>checkAccess</code> method of this thread is called
 * with no arguments. This may result in throwing a
 * <code>SecurityException </code>(in the current thread).
 * <p>
 * If the thread is alive, it is suspended and makes no further
 * progress unless and until it is resumed.
 *
 * @exception  SecurityException  if the current thread cannot modify
 *               this thread.
 * @see #checkAccess
 * @deprecated   This method has been deprecated, as it is
 *   inherently deadlock-prone.  If the target thread holds a lock on the
 *   monitor protecting a critical system resource when it is suspended, no
 *   thread can access this resource until the target thread is resumed. If
 *   the thread that would resume the target thread attempts to lock this
 *   monitor prior to calling <code>resume</code>, deadlock results.  Such
 *   deadlocks typically manifest themselves as "frozen" processes.
 *   For more information, see
 *   <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
 *   are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
 */
@Deprecated
public final void suspend() {
    checkAccess();
    suspend0();
}

/**
 * 恢复执行此线程.
 * <p>
 * First, the <code>checkAccess</code> method of this thread is called
 * with no arguments. This may result in throwing a
 * <code>SecurityException</code> (in the current thread).
 * <p>
 * If the thread is alive but suspended, it is resumed and is
 * permitted to make progress in its execution.
 *
 * @exception  SecurityException  if the current thread cannot modify this
 *               thread.
 * @see        #checkAccess
 * @see        #suspend()
 * @deprecated This method exists solely for use with {@link #suspend},
 *     which has been deprecated because it is deadlock-prone.
 *     For more information, see
 *     <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
 *     are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
 */
@Deprecated
public final void resume() {
    checkAccess();
    resume0();
}

/**
 * 更改线程优先级.
 * <p>
 * First the <code>checkAccess</code> method of this thread is called
 * with no arguments. This may result in throwing a
 * <code>SecurityException</code>.
 * <p>
 * Otherwise, the priority of this thread is set to the smaller of
 * the specified <code>newPriority</code> and the maximum permitted
 * priority of the thread's thread group.
 *
 * @param newPriority priority to set this thread to
 * @exception  IllegalArgumentException  If the priority is not in the
 *               range <code>MIN_PRIORITY</code> to
 *               <code>MAX_PRIORITY</code>.
 * @exception  SecurityException  if the current thread cannot modify
 *               this thread.
 * @see        #getPriority
 * @see        #checkAccess()
 * @see        #getThreadGroup()
 * @see        #MAX_PRIORITY
 * @see        #MIN_PRIORITY
 * @see        ThreadGroup#getMaxPriority()
 */
public final void setPriority(int newPriority) {
    ThreadGroup g;
    checkAccess();
    if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
        throw new IllegalArgumentException();
    }
    if((g = getThreadGroup()) != null) {
        if (newPriority > g.getMaxPriority()) {
            newPriority = g.getMaxPriority();
        }
        setPriority0(priority = newPriority);
    }
}

/**
 * 获取优先级.
 *
 * @return  this thread's priority.
 * @see     #setPriority
 */
public final int getPriority() {
    return priority;
}

/**
 * 更改线程名
 * <p>
 * First the <code>checkAccess</code> method of this thread is called
 * with no arguments. This may result in throwing a
 * <code>SecurityException</code>.
 *
 * @param      name   the new name for this thread.
 * @exception  SecurityException  if the current thread cannot modify this
 *               thread.
 * @see        #getName
 * @see        #checkAccess()
 */
public final synchronized void setName(String name) {
    checkAccess();
    if (name == null) {
        throw new NullPointerException("name cannot be null");
    }

    this.name = name;
    if (threadStatus != 0) {
        setNativeName(name);
    }
}

/**
 * Returns this thread's name.
 *
 * @return  this thread's name.
 * @see     #setName(String)
 */
public final String getName() {
    return name;
}

/**
 * 获取线程ThreadGroup
 *
 * @return  this thread's thread group.
 */
public final ThreadGroup getThreadGroup() {
    return group;
}

/**
 * 返回当前线程@linkplain java.lang.thread group线程组及其子组中活动线程的估计数。递归迭代当前线程线程组中的所有子组。
 *
 * <p> The value returned is only an estimate because the number of
 * threads may change dynamically while this method traverses internal
 * data structures, and might be affected by the presence of certain
 * system threads. This method is intended primarily for debugging
 * and monitoring purposes.
 *
 * @return  an estimate of the number of active threads in the current
 *          thread's thread group and in any other thread group that
 *          has the current thread's thread group as an ancestor
 */
public static int activeCount() {
    return currentThread().getThreadGroup().activeCount();
}

/**
 * 将当前线程的线程组及其子组中的每个活动线程复制到指定的数组中。此方法简单地调用当前线程的线程组的{@链接java.Lang.thRead GroupIy枚举(线程[])}方法。
 *
 * <p> An application might use the {@linkplain #activeCount activeCount}
 * method to get an estimate of how big the array should be, however
 * <i>if the array is too short to hold all the threads, the extra threads
 * are silently ignored.</i>  If it is critical to obtain every active
 * thread in the current thread's thread group and its subgroups, the
 * invoker should verify that the returned int value is strictly less
 * than the length of {@code tarray}.
 *
 * <p> Due to the inherent race condition in this method, it is recommended
 * that the method only be used for debugging and monitoring purposes.
 *
 * @param  tarray
 *         an array into which to put the list of threads
 *
 * @return  the number of threads put into the array
 *
 * @throws  SecurityException
 *          if {@link java.lang.ThreadGroup#checkAccess} determines that
 *          the current thread cannot access its thread group
 */
public static int enumerate(Thread tarray[]) {
    return currentThread().getThreadGroup().enumerate(tarray);
}

/**
 * 当前线程栈帧. 必须先挂起线程.
 *
 * @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();

/**
 * 最多等待@code millis毫秒,此线程将停止。超时@代码0表示永远等待。
 *
 * <p> This implementation uses a loop of {@code this.wait} calls
 * conditioned on {@code this.isAlive}. As a thread terminates the
 * {@code this.notifyAll} method is invoked. It is recommended that
 * applications not use {@code wait}, {@code notify}, or
 * {@code notifyAll} on {@code Thread} instances.
 *
 * @param  millis
 *         the time to wait in milliseconds
 *
 * @throws  IllegalArgumentException
 *          if the value of {@code millis} is negative
 *
 * @throws  InterruptedException
 *          if any thread has interrupted the current thread. The
 *          <i>interrupted status</i> of the current thread is
 *          cleared when this exception is thrown.
 */
public final synchronized void join(long millis)
throws InterruptedException {
    long base = System.currentTimeMillis();
    long now = 0;

    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }

    if (millis == 0) {
        while (isAlive()) {
            wait(0);
        }
    } else {
        while (isAlive()) {
            long delay = millis - now;
            if (delay <= 0) {
                break;
            }
            wait(delay);
            now = System.currentTimeMillis() - base;
        }
    }
}

/**
 * Waits at most {@code millis} milliseconds plus
 * {@code nanos} nanoseconds for this thread to die.
 *
 * <p> This implementation uses a loop of {@code this.wait} calls
 * conditioned on {@code this.isAlive}. As a thread terminates the
 * {@code this.notifyAll} method is invoked. It is recommended that
 * applications not use {@code wait}, {@code notify}, or
 * {@code notifyAll} on {@code Thread} instances.
 *
 * @param  millis
 *         the time to wait in milliseconds
 *
 * @param  nanos
 *         {@code 0-999999} additional nanoseconds to wait
 *
 * @throws  IllegalArgumentException
 *          if the value of {@code millis} is negative, or the value
 *          of {@code nanos} is not in the range {@code 0-999999}
 *
 * @throws  InterruptedException
 *          if any thread has interrupted the current thread. The
 *          <i>interrupted status</i> of the current thread is
 *          cleared when this exception is thrown.
 */
public final synchronized void join(long millis, int nanos)
throws InterruptedException {

    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }

    if (nanos < 0 || nanos > 999999) {
        throw new IllegalArgumentException(
                            "nanosecond timeout value out of range");
    }

    if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
        millis++;
    }

    join(millis);
}

/**
 * 等待此线程死亡.
 *
 * <p> An invocation of this method behaves in exactly the same
 * way as the invocation
 *
 * <blockquote>
 * {@linkplain #join(long) join}{@code (0)}
 * </blockquote>
 *
 * @throws  InterruptedException
 *          if any thread has interrupted the current thread. The
 *          <i>interrupted status</i> of the current thread is
 *          cleared when this exception is thrown.
 */
public final void join() throws InterruptedException {
    join(0);
}

/**
 * 将当前线程的堆栈跟踪打印到标准错误流。此方法仅用于调试。
 *
 * @see     Throwable#printStackTrace()
 */
public static void dumpStack() {
    new Exception("Stack trace").printStackTrace();
}

/**
 * 将此线程标记为@linkplain isdaemon守护进程线程或用户线程。当运行的唯一线程都是守护线程时,Java虚拟机退出。
 *
 * <p> This method must be invoked before the thread is started.
 *
 * @param  on
 *         if {@code true}, marks this thread as a daemon thread
 *
 * @throws  IllegalThreadStateException
 *          if this thread is {@linkplain #isAlive alive}
 *
 * @throws  SecurityException
 *          if {@link #checkAccess} determines that the current
 *          thread cannot modify this thread
 */
public final void setDaemon(boolean on) {
    checkAccess();
    if (isAlive()) {
        throw new IllegalThreadStateException();
    }
    daemon = on;
}

/**
 * Tests if this thread is a daemon thread.
 *
 * @return  <code>true</code> if this thread is a daemon thread;
 *          <code>false</code> otherwise.
 * @see     #setDaemon(boolean)
 */
public final boolean isDaemon() {
    return daemon;
}

/**
 * 确定当前运行的线程是否具有修改此线程的权限。
 * <p>
 * If there is a security manager, its <code>checkAccess</code> method
 * is called with this thread as its argument. This may result in
 * throwing a <code>SecurityException</code>.
 *
 * @exception  SecurityException  if the current thread is not allowed to
 *               access this thread.
 * @see        SecurityManager#checkAccess(Thread)
 */
public final void checkAccess() {
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkAccess(this);
    }
}

/**
 * Returns a string representation of this thread, including the
 * thread's name, priority, and thread group.
 *
 * @return  a string representation of this thread.
 */
public String toString() {
    ThreadGroup group = getThreadGroup();
    if (group != null) {
        return "Thread[" + getName() + "," + getPriority() + "," +
                       group.getName() + "]";
    } else {
        return "Thread[" + getName() + "," + getPriority() + "," +
                        "" + "]";
    }
}

/**
 * 返回此线程的上下文类加载器。上下文类加载器由线程的创建者提供,供加载类和资源时此线程中运行的代码使用。如果不是@linkplain setContextClassloader set,则默认为父线程的Classloader上下文。原始线程的上下文类加载器通常设置为用于加载应用程序的类加载器。.
 *
 * <p>If a security manager is present, and the invoker's class loader is not
 * {@code null} and is not the same as or an ancestor of the context class
 * loader, then this method invokes the security manager's {@link
 * SecurityManager#checkPermission(java.security.Permission) checkPermission}
 * method with a {@link RuntimePermission RuntimePermission}{@code
 * ("getClassLoader")} permission to verify that retrieval of the context
 * class loader is permitted.
 *
 * @return  the context ClassLoader for this Thread, or {@code null}
 *          indicating the system class loader (or, failing that, the
 *          bootstrap class loader)
 *
 * @throws  SecurityException
 *          if the current thread cannot get the context ClassLoader
 *
 * @since 1.2
 */
@CallerSensitive
public ClassLoader getContextClassLoader() {
    if (contextClassLoader == null)
        return null;
    SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        ClassLoader.checkClassLoaderPermission(contextClassLoader,
                                               Reflection.getCallerClass());
    }
    return contextClassLoader;
}

/**
 * 设置此线程的上下文类加载器。创建线程时可以设置上下文类加载器,并允许线程的创建者通过@code getContextClass加载器为加载类和资源时在线程中运行的代码提供适当的类加载器。
 *
 * <p>If a security manager is present, its {@link
 * SecurityManager#checkPermission(java.security.Permission) checkPermission}
 * method is invoked with a {@link RuntimePermission RuntimePermission}{@code
 * ("setContextClassLoader")} permission to see if setting the context
 * ClassLoader is permitted.
 *
 * @param  cl
 *         the context ClassLoader for this Thread, or null  indicating the
 *         system class loader (or, failing that, the bootstrap class loader)
 *
 * @throws  SecurityException
 *          if the current thread cannot set the context ClassLoader
 *
 * @since 1.2
 */
public void setContextClassLoader(ClassLoader cl) {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        sm.checkPermission(new RuntimePermission("setContextClassLoader"));
    }
    contextClassLoader = cl;
}

/**
 * 返回<tt>true<tt>if且仅当当前线程持有指定对象上的监视器锁时
 *
 * <p>This method is designed to allow a program to assert that
 * the current thread already holds a specified lock:
 * <pre>
 *     assert Thread.holdsLock(obj);
 * </pre>
 *
 * @param  obj the object on which to test lock ownership
 * @throws NullPointerException if obj is <tt>null</tt>
 * @return <tt>true</tt> if the current thread holds the monitor lock on
 *         the specified object.
 * @since 1.4
 */
public static native boolean holdsLock(Object obj);

private static final StackTraceElement[] EMPTY_STACK_TRACE
    = new StackTraceElement[0];

/**
 * 返回表示此线程堆栈转储的堆栈跟踪元素数组。如果此线程尚未启动、已启动但尚未计划由系统运行或已终止,则此方法将返回零长度数组。如果返回的数组的长度为非零,则数组的第一个元素表示堆栈的顶部,这是序列中最新的方法调用。数组的最后一个元素表示堆栈的底部,这是序列中最新的方法调用.
 *
 * <p>If there is a security manager, and this thread is not
 * the current thread, then the security manager's
 * <tt>checkPermission</tt> method is called with a
 * <tt>RuntimePermission("getStackTrace")</tt> permission
 * to see if it's ok to get the stack trace.
 *
 * <p>Some virtual machines may, under some circumstances, omit one
 * or more stack frames from the stack trace.  In the extreme case,
 * a virtual machine that has no stack trace information concerning
 * this thread is permitted to return a zero-length array from this
 * method.
 *
 * @return an array of <tt>StackTraceElement</tt>,
 * each represents one stack frame.
 *
 * @throws SecurityException
 *        if a security manager exists and its
 *        <tt>checkPermission</tt> method doesn't allow
 *        getting the stack trace of thread.
 * @see SecurityManager#checkPermission
 * @see RuntimePermission
 * @see Throwable#getStackTrace
 *
 * @since 1.5
 */
public StackTraceElement[] getStackTrace() {
    if (this != Thread.currentThread()) {
        // check for getStackTrace permission
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(
                SecurityConstants.GET_STACK_TRACE_PERMISSION);
        }
        // optimization so we do not call into the vm for threads that
        // have not yet started or have terminated
        if (!isAlive()) {
            return EMPTY_STACK_TRACE;
        }
        StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this});
        StackTraceElement[] stackTrace = stackTraceArray[0];
        // a thread that was alive during the previous isAlive call may have
        // since terminated, therefore not having a stacktrace.
        if (stackTrace == null) {
            stackTrace = EMPTY_STACK_TRACE;
        }
        return stackTrace;
    } else {
        // Don't need JVM help for current thread
        return (new Exception()).getStackTrace();
    }
}

/**
 * Returns a map of stack traces for all live threads.
 * The map keys are threads and each map value is an array of
 * <tt>StackTraceElement</tt> that represents the stack dump
 * of the corresponding <tt>Thread</tt>.
 * The returned stack traces are in the format specified for
 * the {@link #getStackTrace getStackTrace} method.
 *
 * <p>The threads may be executing while this method is called.
 * The stack trace of each thread only represents a snapshot and
 * each stack trace may be obtained at different time.  A zero-length
 * array will be returned in the map value if the virtual machine has
 * no stack trace information about a thread.
 *
 * <p>If there is a security manager, then the security manager's
 * <tt>checkPermission</tt> method is called with a
 * <tt>RuntimePermission("getStackTrace")</tt> permission as well as
 * <tt>RuntimePermission("modifyThreadGroup")</tt> permission
 * to see if it is ok to get the stack trace of all threads.
 *
 * @return a <tt>Map</tt> from <tt>Thread</tt> to an array of
 * <tt>StackTraceElement</tt> that represents the stack trace of
 * the corresponding thread.
 *
 * @throws SecurityException
 *        if a security manager exists and its
 *        <tt>checkPermission</tt> method doesn't allow
 *        getting the stack trace of thread.
 * @see #getStackTrace
 * @see SecurityManager#checkPermission
 * @see RuntimePermission
 * @see Throwable#getStackTrace
 *
 * @since 1.5
 */
public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
    // check for getStackTrace permission
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkPermission(
            SecurityConstants.GET_STACK_TRACE_PERMISSION);
        security.checkPermission(
            SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
    }

    // Get a snapshot of the list of all threads
    Thread[] threads = getThreads();
    StackTraceElement[][] traces = dumpThreads(threads);
    Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);
    for (int i = 0; i < threads.length; i++) {
        StackTraceElement[] stackTrace = traces[i];
        if (stackTrace != null) {
            m.put(threads[i], stackTrace);
        }
        // else terminated so we don't put it in the map
    }
    return m;
}


private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
                new RuntimePermission("enableContextClassLoaderOverride");

/** cache of subclass security audit results */
/* Replace with ConcurrentReferenceHashMap when/if it appears in a future
 * release */
private static class Caches {
    /** cache of subclass security audit results */
    static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
        new ConcurrentHashMap<>();

    /** queue for WeakReferences to audited subclasses */
    static final ReferenceQueue<Class<?>> subclassAuditsQueue =
        new ReferenceQueue<>();
}

/**
 * Verifies that this (possibly subclass) instance can be constructed
 * without violating security constraints: the subclass must not override
 * security-sensitive non-final methods, or else the
 * "enableContextClassLoaderOverride" RuntimePermission is checked.
 */
private static boolean isCCLOverridden(Class<?> cl) {
    if (cl == Thread.class)
        return false;

    processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
    WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
    Boolean result = Caches.subclassAudits.get(key);
    if (result == null) {
        result = Boolean.valueOf(auditSubclass(cl));
        Caches.subclassAudits.putIfAbsent(key, result);
    }

    return result.booleanValue();
}

/**
 *   

对给定的子类执行反射检查,以验证它是否重写安全敏感的非最终方法。如果子类重写任何方法,则返回 true,否则返回 false。
*/
private static boolean auditSubclass(final Class<?> subcl) {
Boolean result = AccessController.doPrivileged(
new PrivilegedAction() {
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();

/**
 *返回线程ID.  The thread ID is a positive
 * <tt>long</tt> number generated when this thread was created.
 * The thread ID is unique and remains unchanged during its lifetime.
 * When a thread is terminated, this thread ID may be reused.
 *
 * @return this thread's ID.
 * @since 1.5
 */
public long getId() {
    return tid;
}

/**
 * 线程状态枚举类.  A thread can be in one of the following states:
 * <ul>
 * <li>{@link #NEW}<br>
 *     A thread that has not yet started is in this state.
 *     </li>
 * <li>{@link #RUNNABLE}<br>
 *     A thread executing in the Java virtual machine is in this state.
 *     </li>
 * <li>{@link #BLOCKED}<br>
 *     A thread that is blocked waiting for a monitor lock
 *     is in this state.
 *     </li>
 * <li>{@link #WAITING}<br>
 *     A thread that is waiting indefinitely for another thread to
 *     perform a particular action is in this state.
 *     </li>
 * <li>{@link #TIMED_WAITING}<br>
 *     A thread that is waiting for another thread to perform an action
 *     for up to a specified waiting time is in this state.
 *     </li>
 * <li>{@link #TERMINATED}<br>
 *     A thread that has exited is in this state.
 *     </li>
 * </ul>
 *
 * <p>
 * A thread can be in only one state at a given point in time.
 * These states are virtual machine states which do not reflect
 * any operating system thread states.
 *
 * @since   1.5
 * @see #getState
 */
public enum State {
    /**
     * Thread state for a thread which has not yet started.
     */
    NEW,

    /**
     * Thread state for a runnable thread.  A thread in the runnable
     * state is executing in the Java virtual machine but it may
     * be waiting for other resources from the operating system
     * such as processor.
     */
    RUNNABLE,

    /**
     * Thread state for a thread blocked waiting for a monitor lock.
     * A thread in the blocked state is waiting for a monitor lock
     * to enter a synchronized block/method or
     * reenter a synchronized block/method after calling
     * {@link Object#wait() Object.wait}.
     */
    BLOCKED,

    /**
     * Thread state for a waiting thread.
     * A thread is in the waiting state due to calling one of the
     * following methods:
     * <ul>
     *   <li>{@link Object#wait() Object.wait} with no timeout</li>
     *   <li>{@link #join() Thread.join} with no timeout</li>
     *   <li>{@link LockSupport#park() LockSupport.park}</li>
     * </ul>
     *
     * <p>A thread in the waiting state is waiting for another thread to
     * perform a particular action.
     *
     * For example, a thread that has called <tt>Object.wait()</tt>
     * on an object is waiting for another thread to call
     * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
     * that object. A thread that has called <tt>Thread.join()</tt>
     * is waiting for a specified thread to terminate.
     */
    WAITING,

    /**
     * Thread state for a waiting thread with a specified waiting time.
     * A thread is in the timed waiting state due to calling one of
     * the following methods with a specified positive waiting time:
     * <ul>
     *   <li>{@link #sleep Thread.sleep}</li>
     *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
     *   <li>{@link #join(long) Thread.join} with timeout</li>
     *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
     *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
     * </ul>
     */
    TIMED_WAITING,

    /**
     * Thread state for a terminated thread.
     * The thread has completed execution.
     */
    TERMINATED;
}

/**
 * Returns the state of this thread.
 * This method is designed for use in monitoring of the system state,
 * not for synchronization control.
 *
 * @return this thread's state.
 * @since 1.5
 */
public State getState() {
    // get current thread state
    return sun.misc.VM.toThreadState(threadStatus);
}

// Added in JSR-166

/**
 * Interface for handlers invoked when a <tt>Thread</tt> abruptly
 * terminates due to an uncaught exception.
 * <p>When a thread is about to terminate due to an uncaught exception
 * the Java Virtual Machine will query the thread for its
 * <tt>UncaughtExceptionHandler</tt> using
 * {@link #getUncaughtExceptionHandler} and will invoke the handler's
 * <tt>uncaughtException</tt> method, passing the thread and the
 * exception as arguments.
 * If a thread has not had its <tt>UncaughtExceptionHandler</tt>
 * explicitly set, then its <tt>ThreadGroup</tt> object acts as its
 * <tt>UncaughtExceptionHandler</tt>. If the <tt>ThreadGroup</tt> object
 * has no
 * special requirements for dealing with the exception, it can forward
 * the invocation to the {@linkplain #getDefaultUncaughtExceptionHandler
 * default uncaught exception handler}.
 *
 * @see #setDefaultUncaughtExceptionHandler
 * @see #setUncaughtExceptionHandler
 * @see ThreadGroup#uncaughtException
 * @since 1.5
 */
@FunctionalInterface
public interface UncaughtExceptionHandler {
    /**
     * Method invoked when the given thread terminates due to the
     * given uncaught exception.
     * <p>Any exception thrown by this method will be ignored by the
     * Java Virtual Machine.
     * @param t the thread
     * @param e the exception
     */
    void uncaughtException(Thread t, Throwable e);
}

// null unless explicitly set
private volatile UncaughtExceptionHandler uncaughtExceptionHandler;

// null unless explicitly set
private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;

/**
 * Set the default handler invoked when a thread abruptly terminates
 * due to an uncaught exception, and no other handler has been defined
 * for that thread.
 *
 * <p>Uncaught exception handling is controlled first by the thread, then
 * by the thread's {@link ThreadGroup} object and finally by the default
 * uncaught exception handler. If the thread does not have an explicit
 * uncaught exception handler set, and the thread's thread group
 * (including parent thread groups)  does not specialize its
 * <tt>uncaughtException</tt> method, then the default handler's
 * <tt>uncaughtException</tt> method will be invoked.
 * <p>By setting the default uncaught exception handler, an application
 * can change the way in which uncaught exceptions are handled (such as
 * logging to a specific device, or file) for those threads that would
 * already accept whatever &quot;default&quot; behavior the system
 * provided.
 *
 * <p>Note that the default uncaught exception handler should not usually
 * defer to the thread's <tt>ThreadGroup</tt> object, as that could cause
 * infinite recursion.
 *
 * @param eh the object to use as the default uncaught exception handler.
 * If <tt>null</tt> then there is no default handler.
 *
 * @throws SecurityException if a security manager is present and it
 *         denies <tt>{@link RuntimePermission}
 *         (&quot;setDefaultUncaughtExceptionHandler&quot;)</tt>
 *
 * @see #setUncaughtExceptionHandler
 * @see #getUncaughtExceptionHandler
 * @see ThreadGroup#uncaughtException
 * @since 1.5
 */
public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        sm.checkPermission(
            new RuntimePermission("setDefaultUncaughtExceptionHandler")
                );
    }

     defaultUncaughtExceptionHandler = eh;
 }

/**
 * Returns the default handler invoked when a thread abruptly terminates
 * due to an uncaught exception. If the returned value is <tt>null</tt>,
 * there is no default.
 * @since 1.5
 * @see #setDefaultUncaughtExceptionHandler
 * @return the default uncaught exception handler for all threads
 */
public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){
    return defaultUncaughtExceptionHandler;
}

/**
 * Returns the handler invoked when this thread abruptly terminates
 * due to an uncaught exception. If this thread has not had an
 * uncaught exception handler explicitly set then this thread's
 * <tt>ThreadGroup</tt> object is returned, unless this thread
 * has terminated, in which case <tt>null</tt> is returned.
 * @since 1.5
 * @return the uncaught exception handler for this thread
 */
public UncaughtExceptionHandler getUncaughtExceptionHandler() {
    return uncaughtExceptionHandler != null ?
        uncaughtExceptionHandler : group;
}

/**
 * Set the handler invoked when this thread abruptly terminates
 * due to an uncaught exception.
 * <p>A thread can take full control of how it responds to uncaught
 * exceptions by having its uncaught exception handler explicitly set.
 * If no such handler is set then the thread's <tt>ThreadGroup</tt>
 * object acts as its handler.
 * @param eh the object to use as this thread's uncaught exception
 * handler. If <tt>null</tt> then this thread has no explicit handler.
 * @throws  SecurityException  if the current thread is not allowed to
 *          modify this thread.
 * @see #setDefaultUncaughtExceptionHandler
 * @see ThreadGroup#uncaughtException
 * @since 1.5
 */
public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
    checkAccess();
    uncaughtExceptionHandler = eh;
}

/**
 * Dispatch an uncaught exception to the handler. This method is
 * intended to be called only by the JVM.
 */
private void dispatchUncaughtException(Throwable e) {
    getUncaughtExceptionHandler().uncaughtException(this, e);
}

/**
 * Removes from the specified map any keys that have been enqueued
 * on the specified reference queue.
 */
static void processQueue(ReferenceQueue<Class<?>> queue,
                         ConcurrentMap<? extends
                         WeakReference<Class<?>>, ?> map)
{
    Reference<? extends Class<?>> ref;
    while((ref = queue.poll()) != null) {
        map.remove(ref);
    }
}

/**
 *  Weak key for Class objects.
 **/
static class WeakClassKey extends WeakReference<Class<?>> {
    /**
     * saved value of the referent's identity hash code, to maintain
     * a consistent hash code after the referent has been cleared
     */
    private final int hash;

    /**
     * Create a new WeakClassKey to the given object, registered
     * with a queue.
     */
    WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
        super(cl, refQueue);
        hash = System.identityHashCode(cl);
    }

    /**
     * Returns the identity hash code of the original referent.
     */
    @Override
    public int hashCode() {
        return hash;
    }

    /**
     * Returns true if the given object is this identical
     * WeakClassKey instance, or, if this object's referent has not
     * been cleared, if the given object is another WeakClassKey
     * instance with the identical non-null referent as this one.
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == this)
            return true;

        if (obj instanceof WeakClassKey) {
            Object referent = get();
            return (referent != null) &&
                   (referent == ((WeakClassKey) obj).get());
        } else {
            return false;
        }
    }
}


// The following three initially uninitialized fields are exclusively
// managed by class java.util.concurrent.ThreadLocalRandom. These
// fields are used to build the high-performance PRNGs in the
// concurrent code, and we can not risk accidental false sharing.
// Hence, the fields are isolated with @Contended.

/** The current seed for a ThreadLocalRandom */
@sun.misc.Contended("tlr")
long threadLocalRandomSeed;

/** Probe hash value; nonzero if threadLocalRandomSeed initialized */
@sun.misc.Contended("tlr")
int threadLocalRandomProbe;

/** Secondary seed isolated from public ThreadLocalRandom sequence */
@sun.misc.Contended("tlr")
int threadLocalRandomSecondarySeed;

/* Some private helper methods */
private native void setPriority0(int newPriority);
private native void stop0(Object o);
private native void suspend0();
private native void resume0();
private native void interrupt0();
private native void setNativeName(String name);

}

  
    展开阅读全文