前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Thread类源码分析(1)

Thread类源码分析(1)

作者头像
黑洞代码
发布2021-01-14 15:45:32
6940
发布2021-01-14 15:45:32
举报

Thread类源码分析(1)

概述


1.Thread常见属性

2.Thread构造方法

3.Thread.start()

4.Thread.run()

第1节 Thread常见属性


我们以JDK 1.8为例,讲解Thread类的一些常见属性。首先分析一下Thread类的声明:

代码语言:javascript
复制
public class Thread implements Runnable

从Thread类的声明可以看出,Thread类其实也是继承了Runnable接口,是Runnable接口的子类。Thread常见属性及其含义如下:

代码语言:javascript
复制
/** ------ 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构造器有如下几种:

代码语言:javascript
复制
/** 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()方法。

代码语言:javascript
复制
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方法。

代码语言:javascript
复制
/**
 * 调用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()方法中。

代码语言:javascript
复制
/**
 * 线程执行的具体任务
 */
@Override
public void run() {
    if (target != null) {
        target.run();
    }
}

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 落叶飞翔的蜗牛 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档