并发编程学习笔记(七、Thread源码分析)

时间:2022-02-24 14:55:46

目录:

  • 常见属性
  • 构造函数
  • start()
  • run()

常见属性:

   /**
* 线程名称
*/
private volatile String name; /**
* 线程优先级
*/
private int priority; /**
* 是否为守护线程,true-是守护线程
*/
private boolean daemon = false; /**
* 可能被执行的Runnable
*/
private Runnable target; /**
* 所属线程组
*/
private ThreadGroup group; /**
* 当前线程所属的ThreadLocal
*/
ThreadLocal.ThreadLocalMap threadLocals = null; /**
* 为子线程提供父线程所继承的值
*/
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; /**
* 当前线程的栈大小,若不指定默认为0;如何使用这个数值取决于JVM
*/
private long stackSize; /**
* 线程的id
*/
private long tid; /**
* 线程序列号
*/
private static long threadSeqNumber; /**
* 线程状态,默认是未启动
*/
private volatile int threadStatus = 0; /**
* 得到下一个线程的序列号
*/
private static synchronized long nextThreadID() {
return ++threadSeqNumber;
} /**
* 为java.util.concurrent.locks.LockSupport.park提供的变量
*/
volatile Object parkBlocker; /**
* 阻塞器锁,主要处理阻塞状况
*/
private volatile Interruptible blocker; /**
* 阻断锁
*/
private final 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;

构造器:

我们看源码可以看出,所有的构造函数都是调用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(); // -------------- 安全校验 start ----------------
SecurityManager security = System.getSecurityManager();
if (g == null) {
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);
}
}
// -------------- 安全校验 end ---------------- // 记录一下未启动线程的个数
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);
} this.stackSize = stackSize;
// 设置线程ID
tid = nextThreadID();
}

start():

 public synchronized void start() {
// 只能启动状态为未启动的线程
if (threadStatus != 0) {
throw new IllegalThreadStateException();
} // 将当前线程添加到线程组中
group.add(this); boolean started = false;
try {
// 将线程置为就绪状态,此函数为JVM层次的
start0();
started = true;
} finally {
try {
// 启动失败后未启动线程数+1
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) { }
}
}
 private native void start0();

run():

 /**
* 线程具体的执行逻辑
*/
@Override
public void run() {
// 若有指定执行的Runnable,跑Runnable的具体逻辑
if (target != null) {
target.run();
}
}