并发基础篇(四)—— java中线程的状态深入浅出

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

转载声明:转载请注明出处,本技术博客是本人原创文章

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 并发基础篇(四)—— java中线程的状态深入浅出

一、线程的五种状态

  线程的生命周期可以大致分为5种,但这种说法是比较旧的一种说法,有点过时了,或者更确切的来说,这是操作系统的说法,而不是java的说法。但对下面所说的六种状态的理解有所帮助,所以也写出来,作为参考。 1. NEW: 线程的新建状态,是指通过New关键字创建了Thread类(或其子类)的对象。 2. RUNNABLE: 这种情况指的是Thread类的对象调用了start()方法,这时的线程就等待时间片轮转到自己这,以便获得CPU;第二种情况是线程在处于RUNNABLE状态时并没有运行完自己的run方法,时间片用完之后回到RUNNABLE状态;还有种情况就是处于BLOCKED状态的线程结束了当前的BLOCKED状态之后重新回到RUNNABLE状态。 3. RUNNING: 这时的线程指的是获得CPU的RUNNABLE线程,RUNNING状态是所有线程都希望获得的状态。 4. DEAD: 处于RUNNING状态的线程,在执行完run方法之后,或者异常退出时,就变成了DEAD状态了。 5. BLOCKED: 这种状态指的是处于RUNNING状态的线程,出于某种原因,比如调用了sleep方法、等待用户输入等而让出当前的CPU给其他的线程。 注意: BLOCKED状态,包括三种类型状态:等待(wait)、睡眠(sleep)、阻塞(申请资源:I\O、对象的锁);

二、线程的六种状态

  在java中,线程的状态其实是六种,对应着枚举类型 Thread.State 的六个枚举常量: NEW BLOCKED RUNNABLE WAITING TIMED_WAITING TERMINATED

1. NEW : 新建状态,至今尚未启动的线程的状态。


 static void NEW() {
          Thread t = new Thread ();//也就是可以理解为刚刚创建thread
         System. out.println(t.getState());
    }

2. BLOCKED: 阻塞状态,受阻塞并且正在等待监视器锁的某一线程的线程状态。


private static void BLOCKED() {

         final Object lock = new Object();

         Runnable run = new Runnable() {

              @Override
              public void run() {
                  for(int i=0; i<Integer.MAX_VALUE; i++){

                       synchronized (lock) {
                          System. out.println(i);
                      }

                 }
             }
         };

         Thread t1 = new Thread(run);
         t1.setName( “t1”);
         Thread t2 = new Thread(run);
         t2.setName( “t2”);

         t1.start();
         t2.start();

    }

3. RUNNABLE: 可运行线程的线程状态。这里其实合并了两种状态(RUNNING、RUNABLE)


private static void RUNNABLE() {
         Thread t = new Thread(){

              public void run(){
                  for(int i=0; i<Integer.MAX_VALUE; i++){
                      System. out.println(i);
                 }
             }

         };

         t.start();
    }

当线程调用了start()方法之后,就是运行状态了。

4. WAITING : 等待状态,表示线程进入状态。进入此状态后,会无限等待,直到其他线程做出一些特定的动作(唤醒通知、中断通知)才会再次运行。


 private static void WAITING() {

          final Object lock = new Object();
         Thread t1 = new Thread(){
              @Override
              public void run() {

                  int i = 0;

                  while(true ){
                       synchronized (lock) {
                           try {
                               lock.wait();//调用这个方法,进入等待状态
                          } catch (InterruptedException e) {
                          }
                          System. out.println(i++);
                      }
                 }
             }
         };

         Thread t2 = new Thread(){
              @Override
              public void run() {

                  while(true ){
                       synchronized (lock) {
                           for(int i = 0; i< 10000000; i++){
                              System. out.println(i);
                          }
                          lock.notifyAll();
                      }

                 }
             }
         };

         t1.setName(^^t1^^);
         t2.setName(^^t2^^);

         t1.start();
         t2.start();
    }

5. TIMED_WAITING : 计时等待状态,此状态与 WAITING 状态有些类似,但它是有时间限制的,即只会等待一段指定的时间,当时间到来前,没有被唤醒或或中断,那么时间到来了,就自动”醒来”,进入RUNNABLE状态。


synchronized (lock) {
   try {
      lock.wait(60 * 1000L);//只会等待一段指定的时间,当时间到来前,没有被唤醒或或中断
   } catch (InterruptedException e) {
   }
   System. out .println(i++);
 }

6. TERMINATED : 终止状态,已终止线程的线程状态。


 private static void TERMINATED() {
         Thread t1 = new Thread();
         t1.start();
         System. out.println(t1.getState());
          try {
             Thread. sleep(1000L);
         } catch (InterruptedException e) {
         }
         System. out.println(t1.getState());
    }

三、线程的状态转换 这里写图片描述

  • 当一个线程执行了start方法后,不代表这个线程就会立即被执行,只代表这个线程处于可运行的状态,最终由OS的线程调度来决定哪个可运行状态下的线程被执行。- 一个线程一次被选中执行是有时间限制的,这个时间段叫做CPU的时间片,当时间片用完但线程还没有结束时,这个线程又会变为可运行状态,等待OS的再次调度;在运行的线程里执行Thread.yeild()方法同样可以使当前线程变为可运行状态。- 在一个运行中的线程等待用户输入、调用Thread.sleep()、调用了其他线程的join()方法,则当前线程变为阻塞状态。- 阻塞状态的线程用户输入完毕、sleep时间到、join的线程结束,则当前线程由阻塞状态变为可运行状态。- 运行中的线程调用wait方法,此线程进入等待队列。- 运行中的线程遇到synchronized同时没有拿到对象的锁标记、等待队列的线程wait时间到、等待队列的线程被notify方法唤醒、有其他线程调用notifyAll方法,则线程变成锁池状态。- 锁池状态的线程获得对象锁标记,则线程变成可运行状态。- 运行中的线程run方法执行完毕或main线程结束,则线程运行结束。

    文章有不当之处,欢迎指正,你也可以关注我的微信公众号: 好好学java,获取优质学习资源。

原文地址:https://sihai.blog.csdn.net/article/details/80255735

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

转载声明:转载请注明出处,本技术博客是本人原创文章

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 并发基础篇(四)—— java中线程的状态深入浅出


 上一篇
并发基础篇(二)——Thread类的API总结 并发基础篇(二)——Thread类的API总结
Thread 类是java中的线程类,提供给用户用于创建、操作线程、获取线程的信息的类。是java线程一切的基础,掌握这个类是非常必须的,先来看一下它的API. 1、字段摘要|static int MAX_PRIORITY|线程可以具有的
2021-04-04
下一篇 
并发基础(三)—— java线程优先级小试牛刀 并发基础(三)—— java线程优先级小试牛刀
一、概述在不同的JVM中(JVM也算是一个操作系统),有着不同的CPU调度算法,对于大部分的JVM来说,优先级也是调度算法中的一个参数。 所以,线程优先级在一定程度上,对线程的调度执行顺序有所影响,但不能用于保证线程的执行顺序,因为优先级仅
2021-04-04