zoukankan      html  css  js  c++  java
  • Java 之 线程的生命周期(线程状态)

    一、线程的生命周期

      (1)新建状态

        new 好了一个线程对象,此时和普通的 Java对象并没有区别。

      (2)就绪

        就绪状态的线程是具备被CPU调用的能力和状态,也只有这个状态的线程才能被CPU调用。即线程调用了 start() 方法

      (3)运行

        运行状态就是当前线程正在被CPU调度执行。

      (4)阻塞

         从运行状态到阻塞状态有几种情况:

          ① sleep() 

          ② wait()

          ③ join()

          ④ suspend() 已过时

         从阻塞回到就绪状态:

          ① sleep() 时间到,sleep() 被打断 interrupt()

          ② notify() 

          ③ 加塞的线程结束

          ④ 占用锁的线程释放锁

          ⑤ resume() 已过时

      (5)死亡

        从运行到死亡:① run()正常结束 ② run()遇到异常但是没处理 ③ 其他线程把你stop()(已过时)

      图解:

    二、线程状态概述

      当线程被创建并启动以后,并没有直接进入执行状态,还有其他的状态。

      在线程的生命周期中, java.lang.Thread.State 这个枚举中给出了六种线程状态:

      

        线程之间的状态转换

      

    三、Timed Waiting (计时等待)

        Timed WaitingAPI中的描述为:一个正在限时等待另一个线程执行一个(唤醒)动作的线程处于这一状态。

         当调用了 sleep 方法之后,当前执行的线程就进入 “休眠状态”,其实就是Timed Waiting(计时等待)

       Demo:

     1 public class MyThread extends Thread {
     2     public void run() {
     3         for (int i = 0; i < 100; i++) {
     4             if ((i) % 10 == 0) {
     5                 System.out.println("‐‐‐‐‐‐‐" + i);
     6             } 
     7         System.out.print(i);
     8         try {
     9             Thread.sleep(1000);
    10             System.out.print(" 线程睡眠1秒!
    ");
    11         } catch (InterruptedException e) {
    12             e.printStackTrace();
    13         }
    14     }
    15 } 
    16 public static void main(String[] args) {
    17     new MyThread().start();
    18     }
    19 }    

       注意

        1. 进入 TIMED_WAITING 状态的一种常见情形是调用的 sleep 方法,单独的线程也可以调用,不一定非要有协作关系

        2.  为了让其他线程有机会执行,可以将Thread.sleep()的调用放线程run()之内。这样才能保证该线程执行过程中会睡眠

        3.  sleep与锁无关,线程睡眠到期自动苏醒,并返回到Runnable(可运行)状态。

      Tips: sleep()中指定的时间是线程不会运行的最短时间。因此,sleep()方法不能保证该线程睡眠到期后就开始立刻执行。

      线程状态图

      

    四、Blocked (锁阻塞)

      Blocked状态在API中的介绍为:一个正在阻塞等待一个监视器锁(锁对象)的线程处于这一状态。
      如当线程 A 与线程B 在代码中使用同一个锁,如果线程 A 获取到锁,线程A 进入 Runnable 状态,那么线程B就进入到 Blocked 锁阻塞状态。

      Blocked 线程状态图

      

    五、Waiting (无限等待)

      Waiting 状态介绍为一个正在无限期等待另一个线程执行一个特别的(唤醒)动作的线程处于这一状态。

      Demo: 

     1 public class WaitingTest {
     2     public static Object obj = new Object();
     3     public static void main(String[] args) {
     4         // 演示waiting
     5         new Thread(new Runnable() {
     6             @Override
     7             public void run() {
     8                 while (true){
     9                     synchronized (obj){
    10                         try {
    11                             System.out.println( Thread.currentThread().getName() +"=== 获取到锁对象,调用wait方法,进入waiting状态,释放锁对象");
    12                             obj.wait(); //无限等待
    13                             //obj.wait(5000); //计时等待, 5秒 时间到,自动醒来
    14                             } catch (InterruptedException e) {
    15                                 e.printStackTrace();
    16                             } 
    17                             System.out.println( Thread.currentThread().getName() + "=== 从waiting状
    18 态醒来,获取到锁对象,继续执行了");
    19                     }
    20                 }
    21         }
    22     },"等待线程").start();
    23 
    24         new Thread(new Runnable() {
    25             @Override
    26             public void run() {
    27             // while (true){ //每隔3秒 唤醒一次
    28             try {
    29                 System.out.println( Thread.currentThread().getName() +"‐‐‐‐‐ 等待3秒钟");
    30                 Thread.sleep(3000);
    31                 } catch (InterruptedException e) {
    32                     e.printStackTrace();
    33                 } 
    34                 synchronized (obj){
    35                     System.out.println( Thread.currentThread().getName() +"‐‐‐‐‐ 获取到锁对
    36 象,调用notify方法,释放锁对象");
    37                     obj.notify();
    38                 }
    39             }
    40     // }
    41     },"唤醒线程").start();
    42     }
    43 }

      一个调用了某个对象的 Object.wait 方法的线程会等待另一个线程调用此对象的 Object.notify() 方法或 Object.notifyAll() 方法。

      注意waiting状态并不是一个线程的操作,它体现的是多个线程间的通信,可以理解为多个线程之间的协作关系,多个线程会争取锁,同时相互之间又存在协作关系。

      扩展

        当多个线程协作时,比如AB线程,如果A线程在Runnable(可运行)状态中调用了wait()方法那么A线程就进入了Waiting(无限等待)状态,同时失去了同步锁。

         假如这个时候B线程获取到了同步锁,在运行状态中调用了notify()方法,那么就会将无限等待的A线程唤醒。注意是唤醒,如果获取到锁对象,那么A线程唤醒后就进入Runnable(可运行)状态;如果没有获取锁对象,那么就进入到Blocked(锁阻塞状态)。

      Waiting 线程状态图:

    六、线程状态转换

      

      Tips

        发现Timed Waiting(计时等待) 与 Waiting(无限等待) 状态联系还是很紧密的,比如Waiting(无限等待) 状态中wait方法是空参的,而timed waiting(计时等待) 中wait方法是带参的。
    这种带参的方法,其实是一种倒计时操作,相当于我们生活中的小闹钟,我们设定好时间,到时通知,可是如果提前得到(唤醒)通知,那么设定好时间在通知也就显得多此一举了,那么这种设计方案其实是一举两得。如果没有得到(唤醒)通知,那么线程就处于Timed Waiting状态,直到倒计时完毕自动醒来;如果在倒计时期间得到(唤醒)通知,那么线程从Timed Waiting状态立刻唤醒。

      

  • 相关阅读:
    用django搭建自己的博客
    python模块调用
    python常用函数
    ubuntu不能访问windows中的文件
    更改ubuntu下mysql的密码
    重拾代码,加油
    java 接收 char字符型
    Git基础
    flask中'bool' object has no attribute '__call__'问题
    基于python的flask的应用实例注意事项
  • 原文地址:https://www.cnblogs.com/niujifei/p/11461111.html
Copyright © 2011-2022 走看看