上一篇文章对Thread的状态转换和其中的部分源码进行了一个说明,今天继续对Thread源码进行解读,有很多涉及到底层的知识,笔者这里也只能进行简单了解,一起看一看吧
前言
JDK版本号:1.8.0_171
在并发操作中,线程作为基本的操作单位,对于其了解的深度或多或少都会影响我们在多线程中的操作,今天就继续对Thread源码进行分析,看一看其中涉及的线程操作,理解下其是如何实现的,当然,由于其大量调用了native方法,我们也只能了解个大概,不过这也不妨碍我们对其更深一步的理解
常量/变量
// 线程名称
private volatile String name;
// 优先级
private int priority;
// 下面这两个暂时还没明白是做什么的
// debug时eetop是有值的
private Thread threadQ;
private long eetop;
/* Whether or not to single_step this thread. */
// 是否是单步执行
private boolean single_step;
/* Whether or not the thread is a daemon thread. */
// 是否是守护线程,默认false
private boolean daemon = false;
/* JVM state */
// 虚拟机状态
private boolean stillborn = false;
/* What will be run. */
// Runnable实现类,最终调用的业务处理代码就在这了
private Runnable target;
/* The group of this thread */
// 所属线程组
private ThreadGroup group;
/* The context ClassLoader for this thread */
// 当前线程的ClassLoader
private ClassLoader contextClassLoader;
/* The inherited AccessControlContext of this thread */
// 当前线程继承的权限控制上下文,和安全机制相关
private AccessControlContext inheritedAccessControlContext;
/* For autonumbering anonymous threads. */
// 自动编号匿名线程,线程名中的编号获取的就是这个变量值
private static int threadInitNumber;
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
// 此线程的本地变量值.此map由ThreadLocal类进行维护,因为这个类在ThreadLocal中是包级私有的
// ThreadLocalMap是一个用于维护线程本地变量的hashmap
ThreadLocal.ThreadLocalMap threadLocals = null;
/*
* InheritableThreadLocal values pertaining to this thread. This map is
* maintained by the InheritableThreadLocal class.
*/
// 与当前线程有关继承过来的本地变量值,由InheritableThreadLocal维护
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
/*
* The requested stack size for this thread, or 0 if the creator did
* not specify a stack size. It is up to the VM to do whatever it
* likes with this number; some VMs will ignore it.
*/
// 线程请求栈大小,未指定则默认0,最终由所使用的虚拟机决定,一些虚拟机会忽略这个参数
private long stackSize;
/*
* JVM-private state that persists after native thread termination.
*/
// 在本地线程终止之后保留jvm私有状态,没搞懂什么意思
private long nativeParkEventPointer;
/*
* Thread ID
*/
// 线程id
private long tid;
/* For generating thread ID */
// 用来生成线程id,tid变量的设置是通过这个值设置的
private static long threadSeqNumber;
/* Java thread status for tools,
* initialized to indicate thread 'not yet started'
*/
// 线程状态,初始化时标记默认未启动
private volatile int threadStatus = 0;
/**
* The argument supplied to the current call to
* java.util.concurrent.locks.LockSupport.park.
* Set by (private) java.util.concurrent.locks.LockSupport.setBlocker
* Accessed using java.util.concurrent.locks.LockSupport.getBlocker
*/
// 用于调用java.util.concurrent.locks.LockSupport.park的参数
// 值由java.util.concurrent.locks.LockSupport.setBlocker设置
// 由java.util.concurrent.locks.LockSupport.getBlocker访问
volatile Object parkBlocker;
/* The object in which this thread is blocked in an interruptible I/O
* operation, if any. The blocker's interrupt method should be invoked
* after setting this thread's interrupt status.
*/
// 可中断I/O操作时这个线程的这个对象处于阻塞状态
// 当线程中断状态被设置时,这个blocker的interrupt方法应该被调用
// 可参考interrupt方法
private volatile Interruptible blocker;
// 设置block用到的对象锁
private final Object blockerLock = new Object();
/* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code
* 设置blocker的值,通过java.nio代码中的 sun.misc.SharedSecrets进行调用
*/
void blockedOn(Interruptible b) {
synchronized (blockerLock) {
blocker = b;
}
}
/**
* The minimum priority that a thread can have.
*/
// 最小优先级
public final static int MIN_PRIORITY = 1;
/**
* The default priority that is assigned to a thread.
*/
// 线程默认优先级
public final static int NORM_PRIORITY = 5;
/**
* The maximum priority that a thread can have.
*/
// 最高优先级
public final static int MAX_PRIORITY = 10;
private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
new RuntimePermission("enableContextClassLoaderOverride");
// 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.
// 以下三个初始未初化的变量专门由java.util.concurrent.ThreadLocalRandom管理
// 这些变量用在并发代码中构建高性能的PRNGs,由于存在共享失败的情况所以我们不能冒险共享
// 因此,这些变量使用注解@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;
其中有很多变量我也不是很明白,这里大家先了解下就好,也不用太过纠结,毕竟有很多涉及到了底层部分,可能要进行JVM的源码学习才能明白做了什么,这里我稍微简单说明下部分变量
eetop
eetop可能有些偏向底层了,网上没有仔细说明的,本地debug的时候确实有值,只是不知道存储的是什么,不过我在stackoverflow上倒是搜到了提问,大家有兴趣可以看看:
https://stackoverflow.com/questions/17104371/what-is-the-eetop-field-on-thread-for
threadLocals/inheritableThreadLocals
threadLocals和inheritableThreadLocals两个变量值我在之后ThreadLocal源码部分会进行说明,这里可以先简单理解,毕竟ThreadLocal也确实比较重要
parkBlocker
parkBlocker的部分涉及到了LockSupport,parkBlocker是用于记录线程是被谁阻塞的。可以通过LockSupport的getBlocker获取到阻塞的对象。用于监控和分析线程用的,后面有时间也会进行LockSupport的源码分析,这里大概了解下就好
构造方法
构造方法还是挺多的,最终调用都是init方法,主要入参为线程组,实现Runnable接口的类,线程名,线程id,线程栈大小,稍后分析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