Fork me on GitHub

并发编程——线程状态(2)

线程的状态

线程的状态很早之前就理解过了,最近翻《并发编程艺术》的书时候,看到有个点之前理解的不太对。

书中的线程状态分类

  1. new 初始状态,线程被构建,但是还没有调用start()方法
  2. runnable 运行状态,java中将操作系统中的就绪和运行两种状态笼统称作”运行中“(这里没有网上常见的Running状态)
  3. blocked 阻塞状态,表示线程阻塞于锁
  4. waiting 等待状态,表示线程进入等待状态,进入该状态表示当前线程需要等待其他线程做出一些特定动作(通知或中断)
  5. time_waiting 超时等待状态,该状态不同于waiting,可以在指定的时间自行返回。(可以看到这里将waiting和time_waiting分开了,这样也很符合我们用jstack命令看到的线程状态信息)
  6. 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
65
66
/**
* Created by zlj on 2019/2/23.
*/
public class ThreadState {

public static void main(String[] args) {
// TimeWaiting 状态的线程
new Thread(new TimeWaiting(), "TimeWaitingThread").start();
// Waiting状态的线程
new Thread(new Waiting(), "WaitThread").start();
// 模拟同步锁 即未抢占到锁的线程为blocked状态的线程
new Thread(new Blocked(), "BlockedThread-1").start();
new Thread(new Blocked(), "BlockedThread-2").start();

}

/**
* 不断的进行睡眠 模拟线程的超时等待状态
*/
static class TimeWaiting implements Runnable {

@Override
public void run() {
while (true) {
SleepUtils.second(1000);
}
}
}

/**
* 该线程在Waiting.class上进行等待 模拟线程的等待状态
*/
static class Waiting implements Runnable {


@Override
public void run() {
while (true) {
synchronized (Waiting.class) {
try {
// 进行等待
Waiting.class.wait();

} catch (InterruptedException e) {

}
}
}
}
}

/**
* 模拟线程阻塞状态,一个线程获取了Blocked.class的锁 并且不会释放该锁
*/
static class Blocked implements Runnable {

@Override
public void run() {
synchronized (Blocked.class) {
while (true) {
SleepUtils.second(1000);
}
}
}
}
}

这里用了jps和jstack命令去观察了线程状态:

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
// blockedThread-2线程阻塞在获取Blocked.class的锁上
"BlockedThread-2" #15 prio=5 os_prio=0 tid=0x000000001a27a800 nid=0x31dc waiting for monitor entry [0x000000001b11e000]
java.lang.Thread.State: BLOCKED (on object monitor)
at lesson.wwj.juc.thread_status.ThreadState$Blocked.run(ThreadState.java:63)
- waiting to lock <0x00000000d5c3e6d0> (a java.lang.Class for lesson.wwj.juc.thread_status.ThreadState$Blocked)
at java.lang.Thread.run(Thread.java:745)
// 获取到了锁
"BlockedThread-1" #14 prio=5 os_prio=0 tid=0x000000001a278800 nid=0x4538 waiting on condition [0x000000001b01e000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at lesson.wwj.juc.thread_status.SleepUtils.second(SleepUtils.java:12)
at lesson.wwj.juc.thread_status.ThreadState$Blocked.run(ThreadState.java:63)
- locked <0x00000000d5c3e6d0> (a java.lang.Class for lesson.wwj.juc.thread_status.ThreadState$Blocked)
at java.lang.Thread.run(Thread.java:745)
// 处于waiting状态的线程
"WaitThread" #13 prio=5 os_prio=0 tid=0x000000001a274000 nid=0x4c84 in Object.wait() [0x000000001af1f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000d5c3b5a0> (a java.lang.Class for lesson.wwj.juc.thread_status.ThreadState$Waiting)
at java.lang.Object.wait(Object.java:502)
at lesson.wwj.juc.thread_status.ThreadState$Waiting.run(ThreadState.java:44)
- locked <0x00000000d5c3b5a0> (a java.lang.Class for lesson.wwj.juc.thread_status.ThreadState$Waiting)
at java.lang.Thread.run(Thread.java:745)
// 处于超时等待的线程
"TimeWaitingThread" #12 prio=5 os_prio=0 tid=0x000000001a25f000 nid=0x5b44 waiting on condition [0x000000001ae1f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at lesson.wwj.juc.thread_status.SleepUtils.second(SleepUtils.java:12)
at lesson.wwj.juc.thread_status.ThreadState$TimeWaiting.run(ThreadState.java:27)
at java.lang.Thread.run(Thread.java:745)

书中的状态转换图

  • 这里要注意的一点:
    阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或者代码块(获取锁)时的状态,但是阻塞在java.concurrent包中Lock接口的线程状态却是等待状态,因为Lock接口对于阻塞的实现均使用了LockSupport类中相关的方法。
-------------本文结束感谢您的阅读-------------

本文标题:并发编程——线程状态(2)

文章作者:夸克

发布时间:2019年02月24日 - 14:02

最后更新:2022年07月01日 - 05:07

原始链接:https://zhanglijun1217.github.io/2019/02/24/并发编程——线程状态(2)/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。