目录
环境:
JDK1.8(其他版本可供参考) 开发工具: idea
其实把注释翻译一遍就可以懂个七七八八的了
打开Thread类
线程是程序中的执行线程。java虚拟机允许应用程序有多个线程并发执行。每个线程都有优先级。优先级较高的线程是优先于优先级较低的线程执行。每个线程也可以标记为守护进程,也可以不标记为守护进程。
每个线程都有一个用于标识的名称。多个线程可能具有相同的名称。如果在未指定名称的情况下创建一个线程,会为其默认生成一个新名称。
public class Thread implements Runnable {}
Thread 类也是实现了Runnable 接口;在Thread的注释还给出了创建线程的两种方式
/** ------ 1. Thread常用属性 ------ **/
//线程名字
private volatile String name;
//优先级
private int priority;
//是否是守护线程
private boolean daemon = false;
//将会被执行的Runnable.
private Runnable target;
//所属的线程组
private ThreadGroup group;
//当前线程的指定栈大小,如果线程的创建者不指定大小,那默认值就是0
//对这个数如何进行操作取决于JVM,有些JVM会忽略掉这个参数
private long stackSize;
//线程id
private long tid;
//用来生成thread ID
private static long threadSeqNumber;
//标识线程状态,默认是线程未启动
private int threadStatus = 0;
//得到下个thread ID
private static synchronized long nextThreadID() {
return ++threadSeqNumber;
}
//当前线程附属的ThreadLocal,而ThreadLocalMap会被ThreadLocal维护)
ThreadLocal.ThreadLocalMap threadLocals = null;
// 主要作用:为子线程提供从父线程那里继承的值
//在创建子线程时,子线程会接收所有可继承的线程局部变量的初始值,以获得父线程所具有的值
//如果一个子线程调用 InheritableThreadLocal 的 get() ,那么它将与它的父线程看到同一个对象
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
//为java.util.concurrent.locks.LockSupport.park提供的变量
volatile Object parkBlocker;
//阻塞器锁,主要用于处理阻塞情况
private volatile Interruptible blocker;
//阻断锁
private Object blockerLock = new Object();
//线程的最低优先级
public final static int MIN_PRIORITY = 1;
//线程的默认优先级
public final static int NORM_PRIORITY = 5;
//线程的最高的优先级
public final static int MAX_PRIORITY = 10;
Thread类的构造器
/** Thread构造器 */
// 无参构造
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
// 用Runnable作为参数的构造器
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);
}
每个构造器都是调用了 init() 方法:创建线程就是在这个方法里完成的(非常重要)
/**
* 初始化线程。
*
* @param 线程组
* @param 目标对象的run()方法被调用
* @param 命名新线程的名称
* @param stack size新线程所需的堆栈大小,或
* 零表示该参数将被忽略
* @param acc要继承的AccessControlContext,或
* AccessController.getContext()为空
* @param inheritThreadLocals如果{@code 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) {
/* 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();
}
}
/* checkAccess regardless of whether or not threadgroup is
explicitly passed in. */
g.checkAccess();
/*
* Do we have the required permissions?
*/
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 */
/* 设置线程id */
tid = nextThreadID();
}
调用 start() :使线程可运行状态(这里会调用start0本地方法),当分配到CPU时间片段时可以执行
/**
* 使此线程开始执行;Java虚拟机
* 调用此线程的 run 方法
* <p>
* 结果是两个线程同时运行
* 当前线程(从调用 start() 方法和另一个线程(它执行
*
* run() 方法)
* <p>
* 多次启动线程是不合法的。
* 注意,线程一旦完成就不能重新启动
* @see #run()
* @see #stop()
*/
public synchronized void start() {
/**
* 线程状态校验,线程必须是0即新建态才能启动
* 一次以上调用会抛出异常:IllegalThreadStateException
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
//通知线程组当前线程即将执行,同时线程组中未启动线程数-1
//线程组会做一些统计的操作
group.add(this);
boolean started = false;
try {
//调用本地方法
//使线程进入可执行(runnable状态)的状态
start0();
started = true;
} finally {
try {
if (!started) {
//启动失败后,修改线程组未启动线程数+1
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
//本地方法
//start0()会新运行一个线程,新线程会调用run()方法
private native void start0();
1. run() 方法
start0()会新运行一个线程,新线程会调用run()方法(yej)
@Override
public void run() {
if (target != null) {
target.run();
}
}
2. 线程真正退出前执行一些清理工作
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;
}