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状态立刻唤醒。

      

  • 相关阅读:
    HTML DOM 06 节点关系
    HTML DOM 05 事件(三)
    HTML DOM 05 事件(二)
    HTML DOM 05 事件(一)
    html DOM 04 样式
    html DOM 03 节点的属性
    html DOM 02 获取节点
    html DOM 01 节点概念
    JavaScript 29 计时器
    JavaScript 28 弹出框
  • 原文地址:https://www.cnblogs.com/niujifei/p/11461111.html
Copyright © 2011-2022 走看看