并发编程系列(四)之Thread类源码分析(一)

目录

1. run()  方法

2. 线程真正退出前执行一些清理工作


序号名称链接地址
1并发编程系列(一)创建线程的三种方式及线程如何完成上下文如何切换https://blog.csdn.net/qq_38130094/article/details/103443997
2并发编程系列(二)之线程的中断https://blog.csdn.net/qq_38130094/article/details/103444171
3 并发系列(三)线程常用的方法https://blog.csdn.net/qq_38130094/article/details/103446126
4并发编程系列(四)之Thread类源码分析(一)https://blog.csdn.net/qq_38130094/article/details/103448160
5并发编程系列(五)volatile关键字详解https://blog.csdn.net/qq_38130094/article/details/103448564
6并发编程系列(六)volatile 之 as-if-serial 指令重排 volatile内存语义 volatile原理https://blog.csdn.net/qq_38130094/article/details/103543998
7线程系列(七)synchronized使用方式https://blog.csdn.net/qq_38130094/article/details/103537663
8 线程系列(八)synchronized实现原理与应用https://blog.csdn.net/qq_38130094/article/details/103537668
9并发编程系列(九)ThreadLocala是如何解决共享变量的并发问题及源码分析https://blog.csdn.net/qq_38130094/article/details/103665098
10并发编程系列(十)AQS同步器独占锁加锁与解锁-源码解读https://blog.csdn.net/qq_38130094/article/details/103540315
11并发编程系列(十一)AQS同步器共享锁加锁解锁源码解读https://blog.csdn.net/qq_38130094/article/details/103646505
12并发编程系列(十二)AQS同步器条件锁(Condition)加锁解锁源码解读https://blog.csdn.net/qq_38130094/article/details/103679146
13发编程系列(十三)ReentrantLock 重入锁https://blog.csdn.net/qq_38130094/article/details/103843779
14发编程系列(十四)Semaphore信号量https://blog.csdn.net/qq_38130094/article/details/103846420
15发编程系列(十五) CountDownLatch闭锁https://blog.csdn.net/qq_38130094/article/details/103855632
16并发编程系列(十六) CyclicBarrierhttps://blog.csdn.net/qq_38130094/article/details/103859704

环境:

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;
}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值