public class Thread implements Runnable {
/* 进行注册,调用本地方法registerNatives */
private static native void registerNatives();
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;
/* 要被运行的目标 */
private Runnable target;
/* 线程所在线程组 */
private ThreadGroup group;
/*线程上下文加载器*/
private ClassLoader contextClassLoader;
/*此线程继承的AccessControlContext*/
private AccessControlContext inheritedAccessControlContext;
/* 用于自动编号匿名线程 */
private static int threadInitNumber;
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
/* 与此线程相关的threadlocal值。此映射由threadlocal类维护。 */
ThreadLocal.ThreadLocalMap threadLocals = null;
/*与此线程相关的可继承线程本地值,此映射由InheritableThreadLocal类维护*/
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
/*
* 此线程请求的堆栈大小,或者如果创建者未指定堆栈大小。vm就会对这个数字做任何满足vm偏好的赋值;有些vm会忽略它。
*/
private long stackSize;
/* 在本机线程终止后持续存在的JVM私有状态*/
private long nativeParkEventPointer;
/*线程ID*/
private long tid;
/* 用于生成线程ID */
private static long threadSeqNumber;
/*Java线程状态的指示工具,已初始化,指示线程“尚未启动”*/
private volatile int threadStatus = 0;
/*生成线程ID*/
private static synchronized long nextThreadID() {
return ++threadSeqNumber;
}
/**
* 提供给当前调用java.util.concurrent.locks.LockSupport.park 的参数
* 由 java.util.concurrent.locks.LockSupport.setBlocker 设置
* 使用 java.util.concurrent.locks.LockSupport.getBlocker 访问
*/
volatile Object parkBlocker;
/* 此线程在可中断I/O操作中被阻塞的对象(如果有)。设置此线程的中断状态后,应调用阻止程序的中断方法。*/
private volatile Interruptible blocker;
private final Object blockerLock = new Object();
/* 设置blocker字段;从java.nio代码通过sun.misc.sharedsecrets调用*/
void blockedOn(Interruptible b) {
synchronized (blockerLock) {
blocker = b;
}
}
/**
* 线程的最低优先级1
*/
public final static int MIN_PRIORITY = 1;
/**
* 线程的默认优先级5
*/
public final static int NORM_PRIORITY = 5;
/**
* 线程可以拥有的最大优先级10
*/
public final static int MAX_PRIORITY = 10;
/**
* 返回对当前正在执行的线程对象的引用
* @return 返回当前正在执行的线程
*/
public static native Thread currentThread();
/*是一个本地方法,提示线程调度器当前线程愿意放弃当前CPU的使用。如果当前资源不紧张,调度器可以忽略这个提示。本质上线程状态一直是RUNNABLE,但是定程度可以理解为RUNNABLE到RUNNING的转换*/
public static native void yield();
/*使当前执行的线程休眠(暂时停止执行)指定的毫秒数的本地方法*/
public static native void sleep(long millis) throws InterruptedException;
/* 使当前执行的线程休眠(暂时停止执行)指定的毫秒数加上指定的纳秒数,取决于系统的精度和精确度及系统的计时器和调度程序。
* 此方法的调用不会引起当前线程放弃任何监听器(monitor)的所有权(ownership).
* @param millis 睡眠时间(毫秒)
* @param nanos 额外睡眠的纳秒*/
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) {
init(g, target, name, stackSize, null, true);
}
/**
* 初始化一个线程
*
* @param g 线程组
* @param target 执行对象
* @param name 线程名
* @param stackSize 新线程栈大小,为0表示忽略
* @param acc 用于继承的访问控制上下文
* @param inheritThreadLocals 如果值为true,从构造线程继承可继承线程局部变量的初始值
*/
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) {
/* 确定它是否是applet应用,如果有安全管理,查询安全管理需要做的工作*/
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();
//下面是各种赋值操作
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);
/* 保存指定的堆栈大小以防vm有相关要求 */
this.stackSize = stackSize;
/* 设置线程id */
tid = nextThreadID();
}
/*抛出clonenotsupportedexception,因为无法有意义地克隆线程,所以不进行克隆。*/
@Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
/*下面是各种初始化线程的方法,都调用了init方法*/
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
Thread(Runnable target, AccessControlContext acc) {
init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
}
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() {
/*对于主方法线程或由虚拟机创建/设置的“系统”组线程,将来添加到此方法的任何新功能可能也必须添加到vm中*/
/* 0状态值代表NEW的状态,线程不能重复start*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* 通知组此线程即将启动,以便可以将其添加到组的线程列表中,小组的未开始计数可以减少 */
group.add(this);
//设立标识符判断线程是否正常启动
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
//通知group,线程尝试启动失败。会移除该进程,未开始进程数nUnstartedThreads增加1
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* 什么都不做。如果start0抛出了一个throwable,那么它将被传递到调用堆栈上 */
}
}
}
//一个Native Method就是一个java调用非java代码的接口,该方法的实现由非java语言实现。
// native method的存在并不会对其他类调用这些本地方法产生任何影响,实际上调用这些方法的其他类甚至不知道它所调用的是一个本地方法。JVM将控制调用本地方法的所有细节。
private native void start0();
/*如果这个线程是用一个单独的Runnable run对象构造的,则调用该对象的方法,否则,此方法将不执行任何操作并返回。
* Thread的子类应重写此方法。*/
@Override
public void run() {
//如果“what will 被 run”不为空就调用run方法
if (target != null) {
target.run();
}
}
/*该方法由系统调用,以便在实际退出之前给线程一个清理的机会*/
private void exit() {
//线程组不为空就终止线程
if (group != null) {
group.threadTerminated(this);
group = null;
}
/* 主动清空所有引用字段:请参阅错误4006245*/
target = null;
/* 加快释放这些资源,赋值为空,交给GC回收掉*/
threadLocals = null;
inheritableThreadLocals = null;
inheritedAccessControlContext = null;
blocker = null;
uncaughtExceptionHandler = null;
}
/* 中划线(删除线)意为:
* 发生这些变化并不会影响编译,只是提醒一下程序员,这个方法以后是要被删除的,最好别用。
* 就是如果一个类从另外一个类继承,并且override被继承类的Deprecated方法,在编译时将会出现一个警告。
* 弃用原因:该方法具有固有的不安全性。
* 用 Thread.stop 来终止线程将释放它已经锁定的所有监视器(作为沿堆栈向上传播的未检查 ThreadDeath 异常的一个自然后果)。
* 如果以前受这些监视器保护的任何对象都处于一种不一致的状态,则损坏的对象将对其他线程可见,这有可能导致任意的行为。
* stop 的许多使用都应由只修改某些变量以指示目标线程应该停止运行的代码来取代。
* 目标线程应定期检查该变量,并且如果该变量指示它要停止运行,则从其运行方法依次返回。
* 如果目标线程等待很长时间(例如基于一个条件变量),则应使用 interrupt 方法来中断该等待。
*/
@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());
}
//弃用,同上
@Deprecated
public final synchronized void stop(Throwable obj) {
throw new UnsupportedOperationException();
}
/**
* 中断此线程。
* 除非当前线程中断自身,这是始终允许的,所以调用此线程的checkAccess方法,这可能会导致抛出SecurityException 。
* 如果该线程阻塞的调用wait() , wait(long) ,或wait(long, int)的方法Object类,或者在join() , join(long) , join(long, int) , sleep(long) ,或sleep(long, int) ,这个类的方法,那么它的中断状态将被清除,并且将收到一个InterruptedException 。
* 如果该线程在可阻止在I / O操作InterruptibleChannel则信道将被关闭,该线程的中断状态将被设置,并且螺纹将收到一个ClosedByInterruptException 。
* 如果该线程在Selector中被阻塞,则线程的中断状态将被设置,并且它将从选择操作立即返回,可能具有非零值,就像调用了选择器的wakeup方法一样。
* 如果以前的条件都不成立,则该线程的中断状态将被设置。
* 中断不存在的线程不需要任何效果。
*/
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
/*只测试此线程是否被中断 ,不清除中断状态*/
public boolean isInterrupted() {
return isInterrupted(false);
}
/*测试某个线程是否被中断。中断状态是否被重置由传递的ClearInterrupted参数决定*/
private native boolean isInterrupted(boolean ClearInterrupted);
/*弃用,可能出现出现死锁情况*/
@Deprecated
public void destroy() {
throw new NoSuchMethodError();
}
/*测试此线程是否处于活动状态。如果线程已启动但尚未死亡,则该线程是活动的。*/
public final native boolean isAlive();
/**
* 挂起线程
* 这种方法已经被弃用,因为它天生就容易死锁。
* 如果目标线程在监视器上持有一个锁,以在挂起关键系统资源时保护该资源,则在恢复目标线程之前,任何线程都无法访问该资源。
* 如果要恢复目标线程的线程在调用resume之前试图锁定此监视器,则会导致死锁。这种死锁通常表现为“冻结”进程。
*/
@Deprecated
public final void suspend() {
checkAccess();
suspend0();
}
/**
* 恢复挂起的线程
* 已经被弃用了
*/
@Deprecated
public final void resume() {
checkAccess();
resume0();
}
/* 改变线程的优先级
* 首先线程的checkAccess方法被无参调用,可能抛出安全异常。
* 否则,该线程的优先级被设置为线程的线程组的指定优先级的最小值和最大允许优先级。*/
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);
}
}
/*线程优先级的get方法*/
public final int getPriority() {
return priority;
}
/*线程名称的set方法,被无参调用会抛异常*/
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);
}
}
/*线程名称的get方法*/
public final String getName() {
return name;
}
/*返回线程组,线程死掉会返回null*/
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();
/* 最多等待参数millis(ms)时长当前线程就会死亡.参数为0时则要持续等待.
* 此方法在实现上:循环调用以this.isAlive()方法为条件的wait()方法.
* 当线程终止时notifyAll()方法会被调用.
* 建议应用程序不要在线程实例上使用wait,notify,notifyAll方法.
* @param millis 等待时间(毫秒)*/
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");
}
//如果等待时间为0,直接等待,否则循环等待到指定时间
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);
}
}
/*toString方法,包含thread's name, priority, and thread group的打印*/
public String toString() {
ThreadGroup group = getThreadGroup();
if (group != null) {
return "Thread[" + getName() + "," + getPriority() + "," +
group.getName() + "]";
} else {
return "Thread[" + getName() + "," + getPriority() + "," +
"" + "]";
}
}
/* 获取上下文类加载器。如果没有,则默认为父进程的上下文类加载器。
CallerSensitive注解可以起到堵住漏洞的作用。
曾经有黑客通过构造双重反射来提升权限,原理是当时反射只检查固定深度的调用者的类,看它有没有特权。
例如固定看两层的调用者(getCallerClass(2))。如果我的类本来没足够权限群访问某些信息,那我就可以通过双重反射去达到目的:
反射相关的类是有很高权限的,而在 我->反射1->反射2 这样的调用链上,反射2检查权限时看到的是反射1的类,这就被欺骗了,导致安全漏洞。
使用CallerSensitive后,getCallerClass不再用固定深度去寻找actual caller(“我”),而是把所有跟反射相关的接口方法都标注上CallerSensitive,
搜索时凡看到该注解都直接跳过,这样就有效解决了前面举例的问题。
*/
@CallerSensitive
public ClassLoader getContextClassLoader() {
if (contextClassLoader == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader.checkClassLoaderPermission(contextClassLoader,
Reflection.getCallerClass());
}
return contextClassLoader;
}
/* 设置此线程的上下文类加载器。上下文可以在创建线程时设置类加载器,并允许线程的创建者提供适当的类加载器,*/
public void setContextClassLoader(ClassLoader cl) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
}
contextClassLoader = cl;
}
/* 如果且仅当当前线程持有指定对象上的监视器锁就返回true,此方法允许程序断言当前线程已持有指定的锁
* @param 测试锁所有权的对象*/
public static native boolean holdsLock(Object obj);
//堆栈元素数组
private static final StackTraceElement[] EMPTY_STACK_TRACE
= new StackTraceElement[0];
/* 返回表示此线程堆栈转储的堆栈跟踪元素数组。如果此线程尚未启动、已启动但尚未计划由系统运行或已终止,则此方法将返回零长度数组。
* 如果返回的数组长度为非零,那么数组的第一个元素表示堆栈的顶部,这是序列中最近的方法调用。
* 数组的最后一个元素表示堆栈的底部,这是序列中最近的方法调用。*/
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();
}
}
/* 返回所有活动线程的堆栈跟踪映射。*/
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");
/* 子类安全审计结果缓存 */
/* 替换为ConcurrentReferenceHashMap(当/如果它出现在将来的版本中) */
private static class Caches {
/* 子类安全审计结果缓存 */
static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits = new ConcurrentHashMap<>();
/* 对已审核子类的弱引用队列。
* ReferenceQueue是引用队列,在检测到适当的可到达性更改后,垃圾回收器将已注册的引用对象添加到该队列中。
* ReferenceQueue是作为 JVM GC与上层Reference对象管理之间的一个消息传递方式,它使得我们可以对所监听的对象引用可达发生变化时做一些处理 */
static final ReferenceQueue<Class<?>> subclassAuditsQueue = new ReferenceQueue<>();
}
/**
* 验证是否可以在不违反安全约束的情况下构造此(可能是子类)实例。
* 子类不能重写安全敏感的非final方法,否则将检查“enableContextClassloadeRoverride”运行时权限。
*/
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<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();
/*返回此线程的标识符。线程ID为正数,唯一的,在其生存期内保持不变。当一个线程被终止时,这个线程id可以被重用。*/
public long getId() {
return tid;
}
/*线程状态*/
public enum State {
NEW,//状态是指线程刚创建, 尚未启动
RUNNABLE,//状态是线程正在正常运行中, 当然可能会有某种耗时计算/IO等待的操作/CPU时间片切换等, 这个状态下发生的等待一般是其他系统资源, 而不是锁, Sleep等
BLOCKED,//这个状态下, 是在多个线程有同步操作的场景, 比如正在等待另一个线程的synchronized 块的执行释放, 或者可重入的 synchronized块里别人调用wait() 方法, 也就是这里是线程在等待进入临界区
WAITING,//这个状态下是指线程拥有了某个锁之后, 调用了他的wait方法, 等待其他线程/锁拥有者调用 notify / notifyAll 一遍该线程可以继续下一步操作, 这里要区分 BLOCKED 和 WATING 的区别, 一个是在临界点外面等待进入, 一个是在理解点里面wait等待别人notify, 线程调用了join方法 join了另外的线程的时候, 也会进入WAITING状态, 等待被他join的线程执行结束
TIMED_WAITING,//这个状态就是有限的(时间限制)的WAITING, 一般出现在调用wait(long), join(long)等情况下, 另外一个线程sleep后, 也会进入TIMED_WAITING状态
TERMINATED;//这个状态下表示 该线程的run方法已经执行完毕了, 基本上就等于死亡了(当时如果线程被持久持有, 可能不会被回收)
}
/*线程状态的get方法*/
public State getState() {
// get current thread state
return sun.misc.VM.toThreadState(threadStatus);
}
/* 当线程由于未捕获异常而突然终止时调用的处理程序接口。*/
@FunctionalInterface
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);
}
/*从指定的映射中移除已在指定引用队列上排队的所有key。*/
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,并在队列中注册。*/
WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
super(cl, refQueue);
hash = System.identityHashCode(cl);
}
/*返回原始引用的标识哈希代码。*/
@Override
public int hashCode() {
return hash;
}
/* 如果给定对象是相同的WeakClassKey实例,则返回true*/
@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;
/*一些私有的有帮助的本地方法 */
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);//设置线程的名称
}
Thread类源码解析
最新推荐文章于 2023-03-19 13:55:00 发布