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


    目录:

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

    常见属性:

     1   /**
     2      * 线程名称
     3      */
     4     private volatile String name;
     5 
     6     /**
     7      * 线程优先级
     8      */
     9     private int priority;
    10 
    11     /**
    12      * 是否为守护线程,true-是守护线程
    13      */
    14     private boolean daemon = false;
    15 
    16     /**
    17      * 可能被执行的Runnable
    18      */
    19     private Runnable target;
    20 
    21     /**
    22      * 所属线程组
    23      */
    24     private ThreadGroup group;
    25 
    26     /**
    27      * 当前线程所属的ThreadLocal
    28      */
    29     ThreadLocal.ThreadLocalMap threadLocals = null;
    30 
    31     /**
    32      * 为子线程提供父线程所继承的值
    33      */
    34     ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
    35 
    36     /**
    37      * 当前线程的栈大小,若不指定默认为0;如何使用这个数值取决于JVM
    38      */
    39     private long stackSize;
    40 
    41     /**
    42      * 线程的id
    43      */
    44     private long tid;
    45 
    46     /**
    47      * 线程序列号
    48      */
    49     private static long threadSeqNumber;
    50 
    51     /**
    52      * 线程状态,默认是未启动
    53      */
    54     private volatile int threadStatus = 0;
    55 
    56     /**
    57      * 得到下一个线程的序列号
    58      */
    59     private static synchronized long nextThreadID() {
    60         return ++threadSeqNumber;
    61     }
    62 
    63     /**
    64      * 为java.util.concurrent.locks.LockSupport.park提供的变量
    65      */
    66     volatile Object parkBlocker;
    67 
    68     /**
    69      * 阻塞器锁,主要处理阻塞状况
    70      */
    71     private volatile Interruptible blocker;
    72 
    73     /**
    74      * 阻断锁
    75      */
    76     private final Object blockerLock = new Object();
    77 
    78     /**
    79      * 最低优先级
    80      */
    81     public final static int MIN_PRIORITY = 1;
    82 
    83     /**
    84      * 默认优先级
    85      */
    86     public final static int NORM_PRIORITY = 5;
    87 
    88     /**
    89      * 最高优先级
    90      */
    91     public final static int MAX_PRIORITY = 10;

    构造器:

    我们看源码可以看出,所有的构造函数都是调用init()方法,所以我们来说说init()方法:

     1 private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc, boolean inheritThreadLocals) {
     2     // 线程名不能为空
     3     if (name == null) {
     4         throw new NullPointerException("name cannot be null");
     5     }
     6     this.name = name;
     7 
     8     // 当前创建的线程的父线程为正在运行的线程
     9     Thread parent = currentThread();
    10 
    11     // -------------- 安全校验 start ----------------
    12     SecurityManager security = System.getSecurityManager();
    13     if (g == null) {
    14         if (security != null) {
    15             g = security.getThreadGroup();
    16         }
    17 
    18         if (g == null) {
    19             g = parent.getThreadGroup();
    20         }
    21     }
    22 
    23     g.checkAccess();
    24 
    25     if (security != null) {
    26         if (isCCLOverridden(getClass())) {
    27             security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
    28         }
    29     }
    30     // -------------- 安全校验 end ----------------
    31 
    32     // 记录一下未启动线程的个数
    33     g.addUnstarted();
    34 
    35     this.group = g;
    36     // 从这便可以得知为什么父线程是守护线程子线程也是守护线程
    37     this.daemon = parent.isDaemon();
    38     // 从这便可以得知为什么子线程的优先级是继承父线程的
    39     this.priority = parent.getPriority();
    40 
    41     if (security == null || isCCLOverridden(parent.getClass())) {
    42         this.contextClassLoader = parent.getContextClassLoader();
    43     } else {
    44         this.contextClassLoader = parent.contextClassLoader;
    45     }
    46 
    47     this.inheritedAccessControlContext = acc != null ? acc : AccessController.getContext();
    48     // 设置线程的执行体
    49     this.target = target;
    50     // 设置线程优先级
    51     setPriority(priority);
    52 
    53     if (inheritThreadLocals && parent.inheritableThreadLocals != null) {
    54         // 为子线程提供从父线程那继承的值
    55         this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
    56     }
    57 
    58     this.stackSize = stackSize;
    59     // 设置线程ID
    60     tid = nextThreadID();
    61 }

    start():

     1 public synchronized void start() {
     2     // 只能启动状态为未启动的线程
     3     if (threadStatus != 0) {
     4         throw new IllegalThreadStateException();
     5     }
     6 
     7     // 将当前线程添加到线程组中
     8     group.add(this);
     9 
    10     boolean started = false;
    11     try {
    12         // 将线程置为就绪状态,此函数为JVM层次的
    13         start0();
    14         started = true;
    15     } finally {
    16         try {
    17             // 启动失败后未启动线程数+1
    18             if (!started) {
    19                 group.threadStartFailed(this);
    20             }
    21         } catch (Throwable ignore) {
    22 
    23         }
    24     }
    25 }
    1 private native void start0();

     run():

     1 /**
     2  * 线程具体的执行逻辑
     3  */
     4 @Override
     5 public void run() {
     6     // 若有指定执行的Runnable,跑Runnable的具体逻辑
     7     if (target != null) {
     8         target.run();
     9     }
    10 }
  • 相关阅读:
    win10系统激活 快捷方式
    echarts 图表自适应外部盒子大小
    JS开发常用工具函数 总结
    课程学习总结报告
    结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程
    基于mykernel 2.0编写一个操作系统内核
    框架复习_SpringMvc
    框架复习_Mybatis
    框架复习_Spring
    IDEA调试
  • 原文地址:https://www.cnblogs.com/bzfsdr/p/11577488.html
Copyright © 2020-2023  润新知