【Java EE】多线程-初阶-线程的状态

发布于:2025-07-30 ⋅ 阅读:(33) ⋅ 点赞:(0)

线程的状态

就绪: 这个线程随时可以去 cpu 上执行.(也包含正在 cpu 上执行)
阻塞: 这个线程暂时不方便去 cpu 上执行.Java 中,针对阻塞状态又做了进一步的细分

3.1 观察线程的所有状态

线程的状态是⼀个枚举类型 Thread.State

public class ThreadState {
 public static void main(String[] args) {
	 for (Thread.State state : Thread.State.values()) {
	 	System.out.println(state);
	 }
 }
}

Java 中,线程有以下几种状态:
NEW: 安排了⼯作, 还未开始⾏动
RUNNABLE: 可⼯作的. ⼜可以分成正在⼯作中和即将开始⼯作.
BLOCKED: 这⼏个都表⽰排队等着其他事情
WAITING: 这⼏个都表⽰排队等着其他事情
TIMED_WAITING: 这⼏个都表⽰排队等着其他事情
TERMINATED: ⼯作完成了.

  1. NEW Thread 对象创建好了,但是还没有调用 start 方法在系统中创建线程
  2. TERMINATED Thread 对象仍然存在,但是系统内部的线程已经执行完毕了
  3. RUNNABLE 就绪状态,表示这个线程正在 cpu 上执行,或者准备就绪随时可以去 cpu 上执行
  4. TIMED WAITING 指定时间的阻塞, 就在到达一定时间之后自动解除阻塞。使用 sleep 会进入这个状态. 使用带有超时时间的join也会
  5. WAITING 不带时间的阻塞 (死等),必须要满足一定的条件,才会解除阻塞。join 或者 wait 都会进入 WAITING
  6. BLOCKED 由于锁竞争,引起的阻塞.(后面线程安全的时候具体介绍)
    在这里插入图片描述

3.2 线程状态和状态转移的意义

在这里插入图片描述
⼤家不要被这个状态转移图吓到,我们重点是要理解状态的意义以及各个状态的具体意思。在这里插入图片描述
还是我们之前的例⼦:
刚把李四、王五找来,还是给他们在安排任务,没让他们⾏动起来,就是 NEW 状态;
当李四、王五开始去窗⼝排队,等待服务,就进⼊到 RUNNABLE 状态。该状态并不表⽰已经被银⾏⼯作⼈员开始接待,排在队伍中也是属于该状态,即可被服务的状态,是否开始服务,则看调度器的调度;
当李四、王五因为⼀些事情需要去忙,例如需要填写信息、回家取证件、发呆⼀会等等时,进⼊BLOCKED 、 WATING 、 TIMED_WAITING 状态,⾄于这些状态的细分,我们以后再详解;
如果李四、王五已经忙完,为 TERMINATED 状态。
所以,之前我们学过的 isAlive() ⽅法,可以认为是处于不是 NEW 和TERMINATED 的状态都是活着的
学习这些状态,最大的作用,调试多线程代码的 bug 的时候,给我们作为重要的参考依据。"程序卡住了"意味着一些关键的线程阻塞了,就可以观察线程的状态,就能分析出一些原因。
如果发现某个进程"卡住了,就可以使用 jconsole 这样的工具,查看这个进程中的一些重要线程的状态和调用栈。通过状态,就可以判定线程是否是阻塞,以及什么原因阻塞的~
在这里插入图片描述
一个 Thread 对象只能 start 一次,和线程状态密切相关的. 只有处于 NEW状态才能 start。WAITING 和 BLOCKED 后面再介绍

3.3 观察线程的状态和转移

观察 1: 关注 NEW 、 RUNNABLE 、 TERMINATED 状态的转换

public class ThreadStateTransfer {
 public static void main(String[] args) throws InterruptedException {
	 Thread t = new Thread(() -> {
	 	for (int i = 0; i < 1000_0000; i++) {
	 	}
 	 }, "李四");
	 System.out.println(t.getName() + ": " + t.getState());;
	 t.start();
	 while (t.isAlive()) {
	 	System.out.println(t.getName() + ": " + t.getState());;
	 }
	 System.out.println(t.getName() + ": " + t.getState());;
 }
}

观察 2: 关注 WAITING 、 BLOCKED 、 TIMED_WAITING 状态的转换

public static void main(String[] args) {
 final Object object = new Object();
 Thread t1 = new Thread(new Runnable() {
	 @Override
	 public void run() {
		 synchronized (object) {
			 while (true) {
				 try {
				 	Thread.sleep(1000);
				 } catch (InterruptedException e) {
				 	e.printStackTrace();
				 }
			 }
		 }
	 }
 }, "t1");
 t1.start();
 Thread t2 = new Thread(new Runnable() {
	 @Override
	 public void run() {
		 synchronized (object) {
		 	System.out.println("hehe");
		 }
	 }
 }, "t2");
 t2.start();
}

使⽤ jconsole 可以看到 t1 的状态是 TIMED_WAITING , t2 的状态是BLOCKED
修改上⾯的代码, 把 t1 中的 sleep 换成 wait

public static void main(String[] args) {
 final Object object = new Object();
 Thread t1 = new Thread(new Runnable() {
	 @Override
	 public void run() {
		 synchronized (object) {
			 try {
				 // [修改这⾥就可以了!!!!!]
				 // Thread.sleep(1000);
				 object.wait();
			 } catch (InterruptedException e) {
			 	e.printStackTrace();
			 }
		 }
	 }
 }, "t1");
 ...
}

使⽤ jconsole 可以看到 t1 的状态是 WAITING
结论:
• BLOCKED 表⽰等待获取锁, WAITING 和 TIMED_WAITING 表⽰等待其他线程发来通知.
• TIMED_WAITING 线程在等待唤醒,但设置了时限; WAITING 线程在⽆限等待唤醒


网站公告

今日签到

点亮在社区的每一天
去签到