zoukankan      html  css  js  c++  java
  • 【Java源码解析】Thread

    简介

    线程本质上也是进程。线程机制提供了在同一程序内共享内存地址空间运行的一组线程。对于内核来讲,它就是进程,只是该进程和其他一下进程共享某些资源,比如地址空间。在Java语言里,Thread类封装了线程相关的特性,使用其进行多线程编程。

    源码解析

    线程状态

     1     public enum State {
     2         NEW,
     3 
     4         RUNNABLE,
     5 
     6         BLOCKED,
     7 
     8         WAITING,
     9 
    10         TIMED_WAITING,
    11 
    12         TERMINATED;
    13     }
    认识3个队列
    1. threadScheduleQueue,线程调度队列,操作系统根据此队列给每个线程分配CPU时间片
    2. synchronousQueue,同步队列,多个线程争用同一把锁时,未抢到锁的线程会在此队列里等待
    3. conditionQueue,条件队列,抢到锁的线程要等待某个条件而释放锁就会进入此队列里被别的拿到锁的线程唤醒。
    三个队列的关系

    一个线程自创建起,一定是先被安排进入threadScheduleQueue,轮到它的时间片投入运行,遇见临界区,抢锁失败后会进入synchronousQueue,可能 要等待某个条件,继而进入conditionQueue,

    如果别的线程唤醒它,离开conditionQueue,进入synchronousQueue,继续抢占锁,执行完同步代码块,最后回到threadScheduleQueue,等待下次被调度。

    线程状态
    • NEW,线程刚刚创建,尚未启动
    • RUNNABLE,可运行,此时线程在threadScheduleQueue
    • BLOCKED,阻塞(在某把锁上),此时线程在synchronousQueue
    • WAITING,等待某个条件,此时线程在conditionQueue
    • TIMED_WAITING,带超时的WAITING
    • TERMINATED,线程终止
    线程状态转换

     

    属性

     1     private volatile char name[]; // 线程名称
     2     private int priority; // 优先级
     3     private Thread threadQ;
     4     private long eetop;
     5     private boolean single_step; // 是否单步执行
     6     private boolean daemon = false; // 是否是守护线程
     7     private boolean stillborn = false;
     8     private Runnable target; // 目标任务
     9     private ThreadGroup group; // 线程组
    10     private ClassLoader contextClassLoader; // 上下文类加载器
    11     private AccessControlContext inheritedAccessControlContext; // 继承的访问控制上下文
    12     private static int threadInitNumber; // 线程编号
    13 
    14     private static synchronized int nextThreadNum() {
    15         return threadInitNumber++;
    16     }
    17 
    18     ThreadLocal.ThreadLocalMap threadLocals = null; // 线程本地变量Map
    19     ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; // 线程本地变量Map,会继承父线程的变量初始值
    20     private long stackSize; // 该线程请求的堆栈大小
    21     private long nativeParkEventPointer;
    22     private long tid; // 线程ID
    23     private static long threadSeqNumber; // 用来生成线程ID
    24     private volatile int threadStatus = 0; // 线程状态
    25 
    26     private static synchronized long nextThreadID() {
    27         return ++threadSeqNumber;
    28     }
    29 
    30     volatile Object parkBlocker; // 中断阻塞器
    31     private volatile Interruptible blocker;
    32     private final Object blockerLock = new Object(); // 阻塞锁
    33 
    34     void blockedOn(Interruptible b) {
    35         synchronized (blockerLock) {
    36             blocker = b;
    37         }
    38     }
    39 
    40     public final static int MIN_PRIORITY = 1; // 线程最小优先级
    41     public final static int NORM_PRIORITY = 5; // 默认优先级
    42     public final static int MAX_PRIORITY = 10; // 最大优先级

    构造方法

     1     public Thread() {
     2         init(null, null, "Thread-" + nextThreadNum(), 0);
     3     }
     4 
     5     public Thread(Runnable target) {
     6         init(null, target, "Thread-" + nextThreadNum(), 0);
     7     }
     8 
     9     Thread(Runnable target, AccessControlContext acc) {
    10         init(null, target, "Thread-" + nextThreadNum(), 0, acc);
    11     }
    12 
    13     public Thread(ThreadGroup group, Runnable target) {
    14         init(group, target, "Thread-" + nextThreadNum(), 0);
    15     }
    16 
    17     public Thread(String name) {
    18         init(null, null, name, 0);
    19     }
    20 
    21     public Thread(ThreadGroup group, String name) {
    22         init(group, null, name, 0);
    23     }
    24 
    25     public Thread(Runnable target, String name) {
    26         init(null, target, name, 0);
    27     }
    28 
    29     public Thread(ThreadGroup group, Runnable target, String name) {
    30         init(group, target, name, 0);
    31     }
    32 
    33     public Thread(ThreadGroup group, Runnable target, String name, long stackSize) {
    34         init(group, target, name, stackSize);
    35     }

    都会调用init方法。

    init()

     1     private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc) {
     2         if (name == null) {
     3             throw new NullPointerException("name cannot be null");
     4         }
     5         this.name = name.toCharArray(); // 线程名称
     6         Thread parent = currentThread(); // 父线程,创建新线程时所在的线程
     7         SecurityManager security = System.getSecurityManager(); // 安全管理
     8         if (g == null) {
     9             if (security != null) {
    10                 g = security.getThreadGroup();
    11             }
    12             if (g == null) {
    13                 g = parent.getThreadGroup();
    14             }
    15         }
    16         g.checkAccess(); // 检查访问权限
    17         if (security != null) {
    18             if (isCCLOverridden(getClass())) {
    19                 security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
    20             }
    21         }
    22         g.addUnstarted(); // 添加线程到组
    23         this.group = g; // 设置线程组
    24         this.daemon = parent.isDaemon(); // 继承父线程的daemon属性
    25         this.priority = parent.getPriority(); // 继承父线程的优先级
    26         if (security == null || isCCLOverridden(parent.getClass())) // 继承父线程的上下文类加载器
    27             this.contextClassLoader = parent.getContextClassLoader();
    28         else
    29             this.contextClassLoader = parent.contextClassLoader;
    30         this.inheritedAccessControlContext = acc != null ? acc : AccessController.getContext();
    31         this.target = target; // 目标任务
    32         setPriority(priority); // 设置优先级
    33         if (parent.inheritableThreadLocals != null) // 如果父线程的可继承线程变量不为空,则传递给子线程
    34             this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
    35         this.stackSize = stackSize;
    36         tid = nextThreadID(); // 设置线程ID
    37     }

    start()

     1     public synchronized void start() {
     2         if (threadStatus != 0) // 校验线程状态,如果已启动,抛出异常
     3             throw new IllegalThreadStateException();
     4 
     5         group.add(this); // 添加到线程组
     6 
     7         boolean started = false;
     8         try {
     9             start0(); // 调用本地方法启动线程
    10             started = true;
    11         } finally {
    12             try {
    13                 if (!started) { // 若启动失败,记录到线程组
    14                     group.threadStartFailed(this);
    15                 }
    16             } catch (Throwable ignore) {
    17             }
    18         }
    19     }
    20 
    21     private native void start0();

    interrupt()

     1     public void interrupt() {
     2         if (this != Thread.currentThread())
     3             checkAccess();
     4 
     5         synchronized (blockerLock) {
     6             Interruptible b = blocker;
     7             if (b != null) {
     8                 interrupt0(); // 设置中断标记
     9                 b.interrupt(this);
    10                 return;
    11             }
    12         }
    13         interrupt0();
    14     }
    15     
    16     private native void interrupt0();

    join()

     1     public final synchronized void join(long millis) throws InterruptedException {
     2         long base = System.currentTimeMillis();
     3         long now = 0;
     4 
     5         if (millis < 0) {
     6             throw new IllegalArgumentException("timeout value is negative");
     7         }
     8 
     9         if (millis == 0) {
    10             while (isAlive()) {
    11                 wait(0); // 调用object的wait()方法
    12             }
    13         } else {
    14             while (isAlive()) { // 带超时的join
    15                 long delay = millis - now;
    16                 if (delay <= 0) {
    17                     break;
    18                 }
    19                 wait(delay); // 调用object的wait()方法
    20                 now = System.currentTimeMillis() - base;
    21             }
    22         }
    23     }

    行文至此结束。

    尊重他人的劳动,转载请注明出处:http://www.cnblogs.com/aniao/p/aniao_thread.html

  • 相关阅读:
    二叉树
    基础1
    tcp/udp
    异步io模块(自定义)
    select+异步
    异步发送请求的几种方式
    多线程,进程实现并发请求
    位解包运算
    从前端程序员的视角看小程序的稳定性保障
    运行node 报错 throw er; // Unhandled 'error' event
  • 原文地址:https://www.cnblogs.com/aniao/p/aniao_thread.html
Copyright © 2011-2022 走看看