Thread机制源码

1 源码解析

1.1构造方法

几个常用的变量
group:线程组 ,线程组包含其他的线程组,形成一个树结构,除了初始线程组外,其他的线程组都会有父线程,线程可以访问当前线程组的信息,不能访问父线程组信息
daemon:守护线程,
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Thread机制源码_第1张图片
实际都是运行了init()方法,我们详细介绍下这方法

//  ThreadGroup g, 线程组,创建的线程被加入到线程组 ,线程组是线程的集合,线程组组成了一个树,除了初始线程组,每个线程组都有一个parent线程组
// Runnable target,用于回调,Thread 的 run() 方法中会转掉该 target 的 run() 方法,这是线程真正处理事务的地方
//String name 线程名称  
// stackSize 创建的线程的栈的大小,如果是0,表明忽略此参数
private void init(ThreadGroup g, Runnable target, String name, long stackSize) {
//调用native层的currentThread函数获取当前环境所在的线程,例如在Activity中,你获取的将是UI线程
        Thread parent = currentThread();//native方法调用到了底层的代码
        if (g == null) {
            g = parent.getThreadGroup();
        }

        g.addUnstarted();//后台线程数加1 
        this.group = g;

        this.target = target;
        this.priority = parent.getPriority();
        this.daemon = parent.isDaemon();
        setName(name);

        init2(parent);

        /* Stash the specified stack size in case the VM cares */
        this.stackSize = stackSize;
        tid = nextThreadID();// //创建线程Id,线程的唯一标识
    }

  private void init2(Thread parent) {
  //获取线程parent的类加载器 ClassLoader类型
        this.contextClassLoader = parent.getContextClassLoader();
        //设置ClassLoader成员变量
        this.inheritedAccessControlContext = AccessController.getContext();//设置访问权限控制环境
        if (parent.inheritableThreadLocals != null) {
        //给当前线程创建ThreadLocalMap对象,并且继承parent的ThreadLocalMap中的数据
        //创建Thread实例的ThreadLoacaleMap。需要用到父线程的ThreadLocaleMap,目的是为了将父线程中的变量副本拷贝一份到当前线程中。 
            //ThreadLocaleMap是一个Entry型的数组,Thread实例会将变量副本保存在这里面。
            this.inheritableThreadLocals = ThreadLocal.createInheritedMap(
                    parent.inheritableThreadLocals);
        }
    }

到这里Thread的初始化完成。

2 线程的生命周期,

1.New(线程创建未启动)
2.RUNNABLE(正在执行中的线程)
3.BLOCKED(被阻塞并且再等在监视器锁释放)调用join()、sleep()、wait()使线程处于Blocked状态
4.WAITING(等待被唤醒)
5.TIMED_WAITING(等待或睡眠一定时间被唤醒)
6.TERMINATED(线程终止,消亡)

1.new状态
new状态是新县城状态,通过new关键字实例化一个Thread对象就生产一个新线程,线程处于new状态的时候,仅仅是一个空线程们还没有分配系统资源,只能启动或者终止,线程调用new方法后,在start前处于新线程状态。
2.Runnable状态
Runnable也称为可运行状态,通过start方法的状态,线程获取了支持其运行的资源,并调度其run方法,这个状态不能想当然的认为是运行状态,因为这时的线程并不总是一直占用处理机,它也有可能不在运行,这是因为还有优先级和调度问题。
3.NOT Runnable状态
NOT Runnable也称为阻塞状态,当以下事件发生时,线程处于该状态:
a:调用supped、sleep方法
b:调用wait方法等待条件变量
c:线程处于I/O请求的等待
4.Dead也称为死亡状态,
run方法运行完毕、其他线程调用该线程的stop方法、异常终止都会使线程处理该状态

3关键方法

3.1 run()方法

Thread机制源码_第2张图片
处理线程中执行的逻辑,如果继承Thread类则必须重写该方法.

3.2 start()方法


 //方法是加了锁的。 
//原因是避免开发者在其它线程调用同一个Thread实例的这个方法,从而尽量避免抛出异常。 
//这个方法之所以能够执行我们传入的Runnable里的run()方法, 
//是应为JVM调用了Thread实例的run()方法。 

  public synchronized void start() {
    
  //检查线程状态是否为0,为0表示是一个新状态,即还没被start()过。不为0就抛出异常。 
       //就是说,我们一个Thread实例,我们只能调用一次start()方法。 
       if (threadStatus != 0 || started)
           throw new IllegalThreadStateException();
从这里开始才真正的线程加入到ThreadGroup组里。 
//再重复一次,前面只是把nUnstartedThreads这个计数器进行了增量,并没有添加线程。 
   //同时,当线程启动了之后,nUnstartedThreads计数器会-1。因为就绪状态的线程少了一条啊!
       group.add(this);

       started = false;
       try {
       //Native方法。这里交由JVM处理,会调用Thread实例的run()方法。 
           nativeCreate(this, stackSize, daemon);
           started = true;
       } finally {
           try {
               if (!started) {
               //如果没有被启动成功,Thread将会被移除ThreadGroup, 
//同时,nUnstartedThreads计数器又增量1了
                   group.threadStartFailed(this);
               }
           } catch (Throwable ignore) {
               /* do nothing. If start0 threw a Throwable then
                 it will be passed up the call stack */
           }
       }
   }

3.3 setPriority()方法

public final void setPriority(int newPriority) {
        ThreadGroup g;
        checkAccess();
        if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
            // Android-changed: Improve exception message when the new priority
            // is out of bounds.
            throw new IllegalArgumentException("Priority out of range: " + newPriority);
        }
        if((g = getThreadGroup()) != null) {
            if (newPriority > g.getMaxPriority()) {
                newPriority = g.getMaxPriority();
            }
            synchronized(this) {
                this.priority = newPriority;
                if (isAlive()) {
                    nativeSetPriority(newPriority);
                }
            }
        }
    }
  //  nativeSetPriority() 才是真正的给执行线程设置优先级, 所以如果不调用 setPriority() 方法, 创建 Thread 对象的时候, 其实压根就没有把线程设置优先级, 只是给 Thread 对象设置变量.

3.4 interrupt()方法

public void interrupt() {
//中断其他线程,需要先判断当前线程是否允许修改其他线程
       if (this != Thread.currentThread())
           checkAccess();

       synchronized (blockerLock) {
           Interruptible b = blocker;
           if (b != null) {
               nativeInterrupt();//nativa方法 终端线程
               b.interrupt(this);
               return;
           }
       }
       nativeInterrupt();
   }

Interruptible是神马我没看到。

join方法

Thread机制源码_第3张图片

  1. 线程安全,
  2. wait(0)方法,表示释放锁,线程进入等待状态

你可能感兴趣的:(Android)