Thread类源码分析
Posted 云析学院
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Thread类源码分析相关的知识,希望对你有一定的参考价值。
云析学院VIP课程授课老师
Thread类源码分析(1)
概述
1.Thread常见属性
2.Thread构造方法
3.Thread.start()
4.Thread.run()
第1节 Thread常见属性
我们以JDK 1.8为例,讲解Thread类的一些常见属性。首先分析一下Thread类的声明:
public class Thread implements Runnable
从Thread类的声明可以看出,Thread类其实也是继承了Runnable接口,是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;
第2节 Thread构造方法
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()方法,重点分析init()方法。
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);
/* 设置stackSize */
this.stackSize = stackSize;
/* 设置线程id */
tid = nextThreadID();
}
第3节 Thread.start()
调用start()方法启动线程,执行线程的run方法。
/**
* 调用start()方法启动线程,执行线程的run方法
* 此方法会导致当前调用start()方法的线程和新线程并发执行
*/
public synchronized void start() {
/**
* 线程状态校验,线程必须是0即新建态才能启动
*/
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 */
}
}
}
// start()实际上是通过本地方法start0()启动线程的。
// start0()会新运行一个线程,新线程会调用run()方法
private native void start0();
第4节 Thread.run()
线程执行的具体任务在run()方法中。
/**
* 线程执行的具体任务
*/
@Override
public void run() {
if (target != null) {
target.run();
}
}
tatget就是Runnable对象——Thread类的run()方法会调用Runnable对象的run()方法。
扫一扫
关注我
●
●
●
●
以上是关于Thread类源码分析的主要内容,如果未能解决你的问题,请参考以下文章
Android 音频源码分析——Thread Track分析
java Thread 类的源码阅读(oracle jdk1.8)
Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段
Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段