jdk1.8线程状态源码翻译学习

文章目录

    • 0.查看阅读文件介绍
    • 1.Thread线程状态
      • 1.1.State枚举描述
      • 1.2线程状态定义
        • 1.1.1NEW状态
        • 1.1.2RUNABLE状态
        • 1.1.3BLOCK状态
        • 1.1.4WAITING状态
        • 1.1.5TIMED_WAITING状态
        • 1.1.6TERMINATED状态
      • 1.3线程状态转换流程图
    • 2.心得总结

0.查看阅读文件介绍

​ Thread类位于rt.jar下的java.lang包中的一个类,从jdk1.0就已经存在的一个类,可以看出其悠久的历史,可能已经被无数人介绍过了,但是为何今天还要再一次进行介绍,别人的永远是别人的,只有自己真真正正的思考过,梳理过才能消化为自己的,我觉得这是一次内化的过程。

1.Thread线程状态

1.1.State枚举描述

    /**
     * A thread state.  A thread can be in one of the following states:
     * 
    *
  • {@link #NEW}
    * A thread that has not yet started is in this state. *
  • *
  • {@link #RUNNABLE}
    * A thread executing in the Java virtual machine is in this state. *
  • *
  • {@link #BLOCKED}
    * A thread that is blocked waiting for a monitor lock * is in this state. *
  • *
  • {@link #WAITING}
    * A thread that is waiting indefinitely for another thread to * perform a particular action is in this state. *
  • *
  • {@link #TIMED_WAITING}
    * A thread that is waiting for another thread to perform an action * for up to a specified waiting time is in this state. *
  • *
  • {@link #TERMINATED}
    * A thread that has exited is in this state. *
  • *
* *

* A thread can be in only one state at a given point in time. * These states are virtual machine states which do not reflect * any operating system thread states. * * @since 1.5 * @see #getState */

​ 由于本人英文不是特别好,所以这里边别写博客,边对英文文档做些翻译,如有不正确,请指教,谢谢各位

​ 在jdk1.8中 介绍了 State 是从jdk1.5之后被引入的一个概念,一个线程可能是如下几个状态之一

  • NEW
    1. 线程还没有开始的时候,则处于该状态(NEW)
  • RUNABLE
    1. 线程在JVM中执行的时候,则处于该状态(RUNABLE)
  • BLOCKING
    1. 线程在等待监视器锁的时候,则处于该状态(BLOCKING)
      2. 注意:这里特别提到了监视器锁,说明锁的实现至少有一种是基于Monitor Lock的形式实现的
  • WAITING
    1. indefinitely:无期限的 perform:执行,工作,运转 particular:指定的
      2. 线程无限期的等待另一个线程执行指定动作的时候,则处于该状态(WAITING)
  • TIMED_WAITING
    1. specified 查词典 只有动词词性,并没有形容词词性。 v. 具体说明;明确规定
      2. 而 specified waiting time 是一个固定搭配短语 意为 指定的等待时间
      3. 线程等待另一个线程执行指定等待时间的动作时,则处于该状态(TIMED_WAITING)
  • TERMINATED
    1. exited 退出(计算机程序)
      2. 线程已经退出,则处于该状态(也就是执行完毕的时候)

​ 词汇解读: given 指定的,已经安排好的,特定的 reflect 反映,表明,显示

​ 最后这段话中还明确的指出,一个线程在指定的时间点只会处于某一个状态(这说明,这些状态是属于互斥事件,某个线程不可能同时拥有两个状态),这些状态是虚拟机的状态,而不能反映出任何操作系统线程的状态。

1.2线程状态定义

​ 在jdk1.8中,线程被定义成枚举类型的六种状态,分别是NEW , RUNABLE , BLOCKED , WAITING , TIMED_WAITING , TERMINATED

1.1.1NEW状态

	/**
     * Thread state for a thread which has not yet started.
     */

​ 一个还没开始线程的状态,也就是调用start方法前的状态

1.1.2RUNABLE状态

    /**
     * Thread state for a runnable thread.  A thread in the runnable
     * state is executing in the Java virtual machine but it may
     * be waiting for other resources from the operating system
     * such as processor.
     */

​ 词汇: processor 处理器; 处理机

​ 可运行线程的线程状态,一个现在在可运行状态是指正在JVM中执行但是还在等待来自操作多系统的其他资源,例如

处理器。

​ jdk1.8里面已经明确指出,Thread 的 RUNABLE状态是在 JVM 中正在执行,但是在执行过程中,还需要获取来自操作系统的资源,比如处理器,这就意味着,即使处于RUNABLE状态也有可能发生等待,而等待发生的位置确实JVM中的底层代码内

1.1.3BLOCK状态

    /**
     * Thread state for a thread blocked waiting for a monitor lock.
     * A thread in the blocked state is waiting for a monitor lock
     * to enter a synchronized block/method or
     * reenter a synchronized block/method after calling
     * {@link Object#wait() Object.wait}.
     * 线程处于阻塞等待一把监视器锁的状态
     * 处于阻塞状态是指等待获得一把监视器锁进入同步代码块/方法 或者 在调用Object.wait() 方法后重新进入
     * 同步代码块/方法,(or 后面的这段描述坑我好久,因该是这样理解,举例,在A线程调用wait()方法后,所处	  * 线程(A)会释放锁,而当A被notify的时候,A线程会从新进入抢锁的状态,在没抢到锁的时候处于阻塞状态)
     */

​ 词汇 block 大块

​ 这段话表达出如下几个含义。

​ 1.线程处于BLOCK状态的原因之一,是没有获取到监视器锁,还有没有其他原因不能确定

​ 2.reenter代表的重入,有这一点可以看出,锁可以分为可重入锁和不可重入锁

1.1.4WAITING状态

	/**
     * Thread state for a waiting thread.
     * A thread is in the waiting state due to calling one of the
     * following methods:
     * 
    *
  • {@link Object#wait() Object.wait} with no timeout
  • *
  • {@link #join() Thread.join} with no timeout
  • *
  • {@link LockSupport#park() LockSupport.park}
  • *
* *

A thread in the waiting state is waiting for another thread to * perform a particular action. * 线程处于等待状态是指,等待另一个线程去计算指定的动作 * * For example, a thread that has called Object.wait() * on an object is waiting for another thread to call * Object.notify() or Object.notifyAll() on * that object. A thread that has called Thread.join() * is waiting for a specified thread to terminate. * 例如,一个已经调用了Object.wait()的线程 正在等待另一个 调用object.notify() * 或者 object.notifyAll() 的线程对象。该已经调用 Thread.join()等待指定线程终止。 * */

​ 处于等待线程的线程状态

​ 一个线程处于等待状态,是由于调用了如下方法中的一个:

  1. 没有超时时间 (调用的是 Object 中的 wait方法 ,而Object 中的 wait 方法调用的是一个 native 方法,这已经超出了Java语言的学习范围,具体的实现就不能得知了,但是wait方法中有描述,这里就不具体介绍了,后面有时间,单独写一篇关于Object(超类的文章))

  2. 同样是没有超时时间(调用的却是本类(Thread类)的join方法)

    //Thread类中的join方法
    /**
     * Waits for this thread to die.
     *	等到当前线程死亡。
     *
     * 

    An invocation of this method behaves in exactly the same * way as the invocation * 此方法的调用与调用的行为完全相同(这里表达的意识就是调用的是重载方法,并没有做其他任何逻辑操作) * *

    * {@linkplain #join(long) join}{@code (0)} *
    * * @throws InterruptedException * if any thread has interrupted the current thread. The * interrupted status of the current thread is * cleared when this exception is thrown. * 如果任何线程打断了当前线程。当出现该异常的时候,当前处于打断状态的线程状态被清空 */
    public final void join() throws InterruptedException { join(0); }

    ​ 调用join方法,join方法又调用了重载方法,传了实参0。

    ​ 词汇: invocation–>调用 behaves–>表现 exactly–>精确地; 准确地; 确切地

    ​ 接下来,再看下调用的重载方法

    /**
     * Waits at most {@code millis} milliseconds for this thread to
     * die. A timeout of {@code 0} means to wait forever.
     *
     * millis --> 毫秒
     * 超过最大等待毫秒的线程将死亡。如果超时时间是0,意味着永久等待
     *
     * 

    This implementation uses a loop of {@code this.wait} calls * conditioned on {@code this.isAlive}. As a thread terminates the * {@code this.notifyAll} method is invoked. It is recommended that * applications not use {@code wait}, {@code notify}, or * {@code notifyAll} on {@code Thread} instances. * * conditioned --> 训练;使习惯于;影响(某事发生的方式); * recommended --> 推荐;举荐;介绍;劝告;建议; * applications --> 申请;请求;申请书;申请表;(尤指理论、发现等的)应用,运用;涂抹;敷用;施用 * 当前实现使用的是循环调用当前类的wait方法,调用的条件时 当前类的 isAlive方法的返回值。 * 当前类的notifyAll() 被调用的时候,当前线程终止。 * 当应用没有使用 wait(),notify(),或者notifyAll() 在当前线程的实例中, join()被推荐。 * 这段文档描述表达的意识,join()是通过循环调用wait(),而前提是 isAlive()返回的是true * 当线程实例没有使用wait(),notify(),notifyAll()这些方法的时候,推荐使用join()方法 * * @param millis * the time to wait in milliseconds * 参数 毫秒 * 等待的毫秒时间 * * @throws IllegalArgumentException * if the value of {@code millis} is negative * negative --> 坏的;有害的;消极的;负面的;缺乏热情的;否定的 * 如果传进来的毫秒数是负数,则抛出改异常 * * @throws InterruptedException * if any thread has interrupted the current thread. The * interrupted status of the current thread is * cleared when this exception is thrown. * 如果任何线程打断了当前线程。当出现该异常的时候,当前处于打断状态的线程状态被清空 */ public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) { while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } }

    ​ isAlive() 为native方法,但可以根据注释理解一下

    /**
     * Tests if this thread is alive. A thread is alive if it has
     * been started and has not yet died.
     * 测试如果当前线程是否存活,线程是否存活指的是已经开始但还没结束 
     *
     * @return  true if this thread is alive;
     *          false otherwise.
     * 如果线程存活返回true,其他情况返回false
     */
    public final native boolean isAlive();
    

    ​ 拓展内容到这里差不多,还是回到状态解读上吧!

  3. LockSupport类中的park()也会造成线程的等待

/**
 * Disables the current thread for thread scheduling purposes unless the
 * permit is available.
 * Disables --> 使丧失能力;使伤残;使无效;使不能运转
 * scheduling --> 安排;为…安排时间;预定;列入,收进(正式目录、清单等中)
 * purposes --> 意图;目的;用途;目标;情势的需要;重要意义;有价值的意义
 * unless --> 除非;除非在…情况下;若非;如果不
 * 
 * 除非许可证可用,否则出于线程调度目的禁用当前线程。
 * 
 * 

If the permit is available then it is consumed and the call * returns immediately; otherwise the current thread becomes disabled * for thread scheduling purposes and lies dormant until one of three * things happens: * * consumed --> 沉迷…的; 充满…的; 消耗,耗费; 吃; 喝; 饮; 使充满; consume的过去分词和过去式; * immediately --> 立即;马上;即刻;接近;紧接;附近;紧接地;直接地 * lies --> 躺; 平躺; 平卧; 平放; 处于,保留,保持; 说谎; 撒谎; 编造谎言; 谎言; 位置; 谎话; * dormant --> 休眠的; 蛰伏的; 暂停活动的 * 如果许可证可用,则立刻使用(许可证),并且立刻返回调用结果 * 否则(许可证不可用)当前线程处于线程调度目的禁用当前线程,知道以下三件事情之一发生: * *

    * *
  • Some other thread invokes {@link #unpark unpark} with the * current thread as the target; or * 其他线程以当前线程作为目标调用unpark();或者 * *
  • Some other thread {@linkplain Thread#interrupt interrupts} * the current thread; or * 其他线程调用Thread类的interrupt(),interrupt了当前线程;或者 * *
  • The call spuriously (that is, for no reason) returns. *
* spuriously --> 虚假地 * that is, for no reason --> 也就是说,没有理由 * 调用错误地(也就是说,没有任何原因)返回 * *

This method does not report which of these caused the * method to return. Callers should re-check the conditions which caused * the thread to park in the first place. Callers may also determine, * for example, the interrupt status of the thread upon return. * report --> 汇报;报告;通报;报道;公布;发表;宣布;(v.) 报道;汇报;报告;记述;调查报告(n.) * caused --> 使发生;造成;引起;导致 * determine --> 决定 * upon --> 强调数目或数量大 * 此方法不报告这些方法中的哪一个导致该方法,调用方应首先重新检查导致线程停止的条件。 * 调用者需要自己确定,例如,返回时线程的中断状态。 * */ public static void park() { UNSAFE.park(false, 0L); }

​ 这里看到,最终调用的是UNSAFE的park(),而Unsafe这个类中的 park() ,又是通过native实现的

​ public native void park(boolean arg0, long arg1);

1.1.5TIMED_WAITING状态

/**
 * Thread state for a waiting thread with a specified waiting time.
 * A thread is in the timed waiting state due to calling one of
 * the following methods with a specified positive waiting time:
 * 一个带有特定的等待超时时间的等待线程的状态
 * 线程处于超时等待,由于调用了以下几个 特定位置等待时间 方法之一
 * 
    *
  • {@link #sleep Thread.sleep}
  • * Thread类的sleep方法 *
  • {@link Object#wait(long) Object.wait} with timeout
  • * Object的带有超时时间的wait(long) 方法 *
  • {@link #join(long) Thread.join} with timeout
  • * Thread类的带有超时时间的join方法 *
  • {@link LockSupport#parkNanos LockSupport.parkNanos}
  • * LockSupport.parkNanos方法 *
  • {@link LockSupport#parkUntil LockSupport.parkUntil}
  • * LockSuppor.parkUntil方法 *
*/

1.1.6TERMINATED状态

/**
 * Thread state for a terminated thread.
 * The thread has completed execution.
 * 停止线程的状态
 * 线程已经完成执行
 */

1.3线程状态转换流程图

jdk1.8线程状态源码翻译学习_第1张图片

​ 重点描述:上图中的 编号 9 需要特殊关注一下,这里会有一个WAITING --> BLOCKED 状态的转换,这种状态切换的场景简单再来描述下。

当A线程在sync代码块中调用了wait()后,那么,A线程会释放掉锁,此时A线程处于WAITING状态(阻塞状态),当B线程调用notify()后,线程A被唤醒,阻塞状态接触,但是会进入到等待锁的状态,在没有拿到锁从新执行后续代码的这段时间内,线程A是处于阻塞状态的

2.心得总结

​ 使用多线程,是借助现代CPU的多核特性,使用空间+资源,换取代码的执行效率,了解线程状态是使用线程的基础,从这里开始,希望自己英文翻译的能力能够有所提高,同时对Java的掌握能更上一个台阶。

你可能感兴趣的:(个人原创分享)