Thread类源码分析

Posted 云析学院

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Thread类源码分析相关的知识,希望对你有一定的参考价值。





云析学院VIP课程授课老师



Thread类源码分析(1)

Thread类源码分析(1)

概述


    1.Thread常见属性

    2.Thread构造方法

    3.Thread.start()

    4.Thread.run()

Thread类源码分析(1)

第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;//线程idprivate long tid;//用来生成thread IDprivate static long threadSeqNumber;//标识线程状态,默认是线程未启动private int threadStatus = 0;//得到下个thread IDprivate 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类源码分析(1)

第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();}

Thread类源码分析(1)

第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();
Thread类源码分析(1)

第4节  Thread.run()


    线程执行的具体任务在run()方法中。

/** * 线程执行的具体任务 */@Overridepublic void run() { if (target != null) { target.run(); }}

    tatget就是Runnable对象——Thread类的run()方法会调用Runnable对象的run()方法

Thread类源码分析(1)

一扫

Thread类源码分析(1)


注我




以上是关于Thread类源码分析的主要内容,如果未能解决你的问题,请参考以下文章

Android 音频源码分析——Thread Track分析

java Thread 类的源码阅读(oracle jdk1.8)

Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段

Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段

java Thread源码分析

我的jdk源码:Thread类