Saul's blog Saul's blog
首页
后端
分布式
前端
更多
分类
标签
归档
友情链接
关于
GitHub (opens new window)

Saul.J.Wu

立身之本,不在高低。
首页
后端
分布式
前端
更多
分类
标签
归档
友情链接
关于
GitHub (opens new window)
  • Java入门基础

  • Java核心基础

    • 多线程

      • 基本概念
      • 线程的创建和使用
      • 线程的生命周期
        • 前言
        • Thread.State
        • 线程状态转换图
          • 就绪
          • 阻塞
          • 死亡
      • 线程的同步
      • 线程的通信
      • Callable和线程池
    • Java常用类

    • 枚举类与注解

    • Java集合

    • 数据结构与算法

    • 泛型

    • IO流

    • 网络编程

    • 反射

    • 函数式编程

  • 设计模式

  • Web开发

  • SpringBoot

  • 微服务

  • Elasticsearch

  • 运维

  • 后端
  • Java核心基础
  • 多线程
SaulJWu
2020-12-20

线程的生命周期

# 前言

前面我们学习了线程的创建和使用,接下来学习它的生命周期。

所谓生命周期,就是它的创建到毁灭的周期。

# Thread.State

在Java中,JDK中用Thread.State类定义了线程的几种状态,代表它的声明周期。

State类是Thread类的内部枚举类。我们可以来看看它的源码:

public enum State {
        /**
         * Thread state for a thread which has not yet started.
         */
        NEW,

        /**
         * 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.
         */
        RUNNABLE,

        /**
         * 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}.
         */
        BLOCKED,

        /**
         * Thread state for a waiting thread.
         * A thread is in the waiting state due to calling one of the
         * following methods:
         * <ul>
         *   <li>{@link Object#wait() Object.wait} with no timeout</li>
         *   <li>{@link #join() Thread.join} with no timeout</li>
         *   <li>{@link LockSupport#park() LockSupport.park}</li>
         * </ul>
         *
         * <p>A thread in the waiting state is waiting for another thread to
         * perform a particular action.
         *
         * For example, a thread that has called <tt>Object.wait()</tt>
         * on an object is waiting for another thread to call
         * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
         * that object. A thread that has called <tt>Thread.join()</tt>
         * is waiting for a specified thread to terminate.
         */
        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:
         * <ul>
         *   <li>{@link #sleep Thread.sleep}</li>
         *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
         *   <li>{@link #join(long) Thread.join} with timeout</li>
         *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
         *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
         * </ul>
         */
        TIMED_WAITING,

        /**
         * Thread state for a terminated thread.
         * The thread has completed execution.
         */
        TERMINATED;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
  • 1、NEW:线程对象被新建,但是未启动
  • 2、RUNNABLE:线程运行起来
  • 3、BLOCKED:线程阻塞
  • 4、WAITING:线程等待状态
  • 5、TIMED_WAITING:具有指定等待时间的等待线程的线程状态
  • 6、TERMINATED:消亡

在Java中,它是通过方法来定义它的状态,其实它的状态我们可以重新定义,以至于让我们更加快能理解它的状态。

要想实现多线程,必须在主线程中创建新的线程对象。Java语言使用Thread类及其子类的对象来表示线程,在它的一个完整的生命周期中通常要经历如下的五种状态:

  • 1、新建:当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态
  • 2、就绪:处于新建状态的线程被start()后,将进入线程队列等待CPU时间片,此时它已具备了运行的条件,只是没分配到CPU资源
  • 3、运行:当就绪的线程被调度并获得CPU资源时,便进入运行状态,run()方法定义了线程的操作和功能
  • 4、阻塞:在某种特殊情况下,被人为挂起或执行输入输出操作时,让出CPU并临时中止自己的执行,进入阻塞状态
  • 5、死亡:线程完成了它的全部工作或线程被提前强制性地中止或出现异常导致结束

# 线程状态转换图

image-20201220012917877

说明:

  • 1、生命周期关注两个概念:状态、相应的方法
  • 2、关注一个状态到另一个状态,执行了哪个回调方法
  • 3、关注调用方法,导致状态变化
  • 4、阻塞:临时状态
  • 5、死亡:最终状态

# 就绪

注意:线程调用了start()方法它不会立刻运行,而是进入就绪状态,等待CPU分配资源获取执行权,才会去运行。

像之前的案例调用线程的时候,它的执行顺序并不是从上到下执行的,而是等待CPU分配资源获取执行权:

class Window2 implements Runnable {

    private int ticket = 100;

    public void run() {
        while (true) {
            if (ticket > 0) {
                System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
                ticket--;
            } else {
//                System.out.println(Thread.currentThread().getName() + "抢不到票,卖光了!");
                break;
            }
        }
    }


}

public class WindowTest2 {
    public static void main(String[] args) {
        Window2 w1 = new Window2();
        Thread t1 = new Thread(w1);
        Thread t2 = new Thread(w1);
        Thread t3 = new Thread(w1);java
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 阻塞

阻塞不是线程的最终状态,线程的最终状态只能是死亡。

如果程序一直是阻塞状态,那么这个程序很大问题。

等待同步锁

是指为了解决多线程并发时的安全问题,都想去操作数据,只让一个线程去操作,其他线程要等待获取同步锁,才结束阻塞状态。

join

当别的线程A调用了join状态,那么B线程就进入阻塞状态,当A执行完了,B才会结束阻塞状态。

sleep

当线程调用sleep方法,那么线程就进入阻塞状态,当时间到了,自动回到就绪状态。

suspend():线程挂起,已经被弃用

  • This method has been deprecated, as it is inherently deadlock-prone. If the target thread holds a lock on the monitor protecting a critical system resource when it is suspended, no thread can access this resource until the target thread is resumed. If the thread that would resume the target thread attempts to lock this monitor prior to calling resume, deadlock results. Such deadlocks typically manifest themselves as "frozen" processes. For more information, see Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?.

为什么被弃用?因为它可能会导致死锁,什么是死锁一会后面说。

resume():线程结束结束挂起状态

  • This method exists solely for use with suspend(), which has been deprecated because it is deadlock-prone. For more information, see Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?.

这个方法一般搭配suspend()一起使用,它们是一对出现的。

# 死亡

  • Errror或Exception且未处理

stop():调用线程的stop()方法

线程还没运行完就被强制消亡。

帮我改善此页面 (opens new window)
#线程#生命周期
上次更新: 2020/12/23, 03:15:32
线程的创建和使用
线程的同步

← 线程的创建和使用 线程的同步→

最近更新
01
zabbix学习笔记二
02-28
02
zabbix学习笔记一
02-10
03
Linux访问不了github
12-08
更多文章>
Theme by Vdoing | Copyright © 2020-2022 Saul.J.Wu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式