欢迎光临
我们一直在努力

面试官:谈谈对Java的线程理解,WAITING与BLOCKED状态有什么的区别?

一、系统线程的生命周期

1.1、初始状态

  • 线程已经被创建,但是不允许分配CPU执行

1.2、可运行状态(就绪状态)

  • 指该线程已经被创建(与操作系统线程关联),可以由 CPU 调度执行

1.3、运行状态

  • 操作系统中存在空闲的CPU,会将这个空闲的CPU分配给一个处于可运行状态的线程,线程的状态就转换成了【运行状态】
  • 当 CPU 时间片用完,会从【运行状态】转换至【可运行状态】,会导致线程的上下文切换

1.4、阻塞状态

  • 【运行状态】的线程调用了阻塞的API(例如,以阻塞的方式读文件)或者等待某个事件(例如,等待某个条件变量等)
  • 这时该线程实际不会用到 CPU,会导致线程上下文切换,进入【阻塞状态】,线程会释放CPU资源
  • 等操作完毕,会由操作系统唤醒阻塞的线程,转换至【可运行状态】
  • 与【可运行状态】的区别是,对【阻塞状态】的线程来说只要它们一直不唤醒,调度器就一直不会考虑调度它们

1.5、终止状态

表示线程已经执行完毕,生命周期已经结束,不会再转换为其它状态

如下图: 在这里插入图片描述

注意:此处与Java线程的生命周期有所不同


二,Java线程的生命周期

1.1、初始(NEW):

  • 创建了一个线程对象,使用new关键字实例化一个Thread类或其子类时,但还没有调用start()方法。

1.2、运行(RUNNABLE)

  • Java线程中运行状态包含:就绪(ready)和运行中(running)两种状态
  • 线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法
  • 线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)
  • 就绪状态的线程在获得CPU时间片后变为运行中状态(running)

1.3、阻塞(BLOCKED):

  • 线程阻塞于锁,synchronized没有竞争到锁

提醒:synchronized没有竞争到锁,获取到monitor锁

1.4、等待(WAITING):

  • 进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)

注意:等待的方法wait()、LockSupport.park()、t.join()

1.5、超时等待(TIMED_WAITING)

  • 该状态不同于WAITING,它可以在指定的时间后自行返回

提醒:超时等待的方法Thread.sleep(1)/wait(1)/LockSupport.park(1)/t.join(1)

1.6、终止(TERMINATED)

  • 当线程的run()方法执行完毕或者因为异常而结束时,线程将进入终止状态

如下图: 在这里插入图片描述


三,Java线程线程有几种方式?

按照Java源码中Thread上的注释,只有两种:

  • 派生自Thread类
  • 实现Runnable接口 在这里插入图片描述

提醒: 1,线程池方式,本质上是线程复用,而不是创建线程 2,基于Callable接口的方式,是把实现了Callable接口的对象通过FutureTask包装成Runnable,交给Thread去执行和实现Runnable接口是同一类

public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/

void run();
}


四,Java线程和系统线程的关系

  • 内核线程映射:采用一对一模型
  • 特点:每个 Java 线程直接绑定一个操作系统内核线程
  • 优势:充分发挥多核 CPU 性能,实现操作系统级别的并行处理

五、Java线程状态:阻塞 vs 等待区别

1.1,阻塞状态(BLOCKED)

特点

  • synchronized锁竞争:线程试图获取被其他线程持有的monitor锁
  • 主动竞争:线程主动参与锁的竞争过程
  • 状态特征:线程处于BLOCKED状态

触发场景

  • 进入synchronized块/方法时锁已被占用
  • 重新进入synchronized块时锁被占用

1.2、等待状态(WAITING/TIMED_WAITING)

特点

  • 被动等待:线程通过调用特定方法进入等待状态
  • 主动让出:线程主动释放CPU和锁资源
  • 状态特征:线程处于WAITING或TIMED_WAITING状态

触发场景

  • Object.wait()
  • Thread.join()
  • LockSupport.park()

1.3、区别

状态上下文CPU锁占用唤醒方式唤醒方式
阻塞状态 保持 不消耗CPU时间片 线程持有锁失败,处于锁竞争状态 持有锁的线程释放锁后唤醒竞争 由JVM调度器管理竞争
等待状态 保持 不消耗CPU时间片 线程主动释放锁 由程序逻辑控制唤醒时机 由程序逻辑控制唤醒时机

六、总结

Java线程的生命周期与系统线程不同,但二者之间存在一对一的对应关系,WAITING和BLOCKED主要区别如下:

  • WAITING有三个主要来源:wait()、join()、park()
  • WAITING需要被主动唤醒(除了超时版本)
  • BLOCKED只有一个来源:synchronized锁竞争
  • BLOCKED是自动的,锁释放后系统自动调度

精彩博文

  • Java性能优化实战之并发编程
  • 深入理解进程和线程的区别
  • 大厂二面挂了!问 “ThreadLocal 为什么内存泄漏”,我背了弱引用,面试官:那为什么内存还是会溢出?
  • 赞(0)
    未经允许不得转载:171主机测评 » 面试官:谈谈对Java的线程理解,WAITING与BLOCKED状态有什么的区别?
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址