谈谈你对Java线程5种状态流转原理的理解?

简介: 今天,有位工作5年的小伙伴被问到这样一道面试题,说谈谈你对Java线程5种状态流转原理的理解。当时,平时只关注过线程如何定义和使用,对于线程状态流转脑海一片空白,完全懵了。于是找到我,希望我拍一期视频。今天,我给大家分享一下我的理解。

今天,有位工作5年的小伙伴被问到这样一道面试题,说谈谈你对Java线程5种状态流转原理的理解。当时,平时只关注过线程如何定义和使用,对于线程状态流转脑海一片空白,完全懵了。于是找到我,希望我拍一期视频。


今天,我给大家分享一下我的理解。

1、线程定义

回答线程流转原理这个问题之前,我们先来回忆一下JDK中3种自定义线程的方式以及它们的优缺点。

0d4d4460963ba72bc63e9e9ac25c172f.jpg

第1种:是继承Thread类。如代码所示:

public class MyThread extends Thread{
public void run(){
// to do something
}
}

这种方式的优点是:实现简单,只需实例化继承类的实例,即可使用线程。


它的缺点是:扩展性不足,Java是单继承的语言,如果一个类已经继承了其他类,就无法通过这种方式实现自定义线程

d0ccb5f767aea8bd96971734254713da.jpg

第2种:是实现 Runnable 接口,如代码所示:

public class MyThread implements Runable{
public void run(){
// to do something
}
}

它的优点是:扩展性好,可以在此基础上继承其他类,非常适合多线程处理一份资源的场景


它的缺点是:构造线程实例的过程相对繁琐一点

71297b80255445e30aeabb09c6d97d38.jpg

第3种:是实现Callable接口,如代码所示:

public class MyThread implements Callable<String>{
public String call() throws Exception{
// to do something
return null;
}
}

它的优点是:扩展性好,能支持回调并得到返回值,而且可以抛出受检查异常。


它的缺点是:相较于实现Runnable接口的方式,调用过程较为繁琐。

2、线程状态流转原理

首先来看这样一张图,它涵盖了Java 中多线程各重要知识点。如果掌握了此图,Java 中的多线程也就基本上掌握了。

51cc95afffcdcfcf54fdf1fc00ad1aca.jpg

从图中可以看出,线程状态的流转,一共包括以下 5 种情形:

c137b2bdbaa2f3a5bfc4de21299987df.jpg

1. 新建状态(New): 线程对象创建后,就进入了新建状态。例如,Thread thread = new Thread()。

5622c52d484f052e832b1e0920e1868a.jpg

b450a2486cbf49a7d0152708d7df14fa.jpg

2. 就绪状态(Runnable): 也被称为“可执行状态”。线程对象被创建后,其它线程调用了线程的start()方法,从而来启动该线程。这个时候,线程处于就绪状态,它随时可能被CPU调度执行。

7644f93fd4e21df9ba45ad73c064644e.jpg

72bdc75af64b3f60bdf9c03453266b8b.jpg

3. 运行状态(Running): 是指线程获取CPU资源后,正在运行。需要注意的是,线程只能从就绪状态进入到运行状态。

e1d49bd264815a1853402e97b1bcbd67.jpg

471d47aeac2413aa7341e369f65ae44e.jpg

4. 阻塞状态(Blocked): 是指线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。


那么,阻塞又分为三种情况:


1) 等待阻塞,指通过调用线程的wait()方法,让线程等待。


2) 同步阻塞 ,指线程在获取synchronized同步锁时,因为锁被其它线程所占用而导致获取失败,会进入同步阻塞状态。


3) 其他阻塞,是指通过调用线程的sleep()方法 或者 join()方法 又或者 发出了I/O请求的时候,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

9434de82e23e6fb8946df939e714390a.jpg

977bbb50677959e16c99f7b504a4a0fe.jpg

5. 死亡状态(Dead): 是指线程执行完毕或者因异常退出了run()方法,线程结束生命周期。

906eb37725b830a287b895cf8f934864.jpg

75fc5d32a1a42004eff7c839ecc63c35.jpg

举个通俗一点的例子来解释上面五种状态,比如我们平时去商场上厕所,准备去上厕所就是新建状态(new),上厕所要排队,排队就是就绪状态(Runnable),有坑位了,轮到你了,蹲坑就是运行状态(Running),蹲完坑发现没有手纸,需要等待其他人送纸过来,这个状态就是阻塞(Blocked),等上完厕所出来,上厕所这件事情结束了线程也就不存在了,就是死亡状态。


需要注意的是:便秘也是阻塞状态,你便秘太久,其他人会等不及,可能会把你赶走,这个就是挂起。还有一种情况就是,如果你便秘占坑位太久,其他人跟你说,先出去酝酿一下,5分钟后再过来蹲坑,这就叫睡眠。


好了,以上就是我对线程状态流转原理的理解。


我是被编程耽误的文艺Tom,关注我,面试不再难!

b47a6e98314749488df58a0cfbc33b50.gif

相关文章
|
4天前
|
Java Linux 调度
硬核揭秘:线程与进程的底层原理,面试高分必备!
嘿,大家好!我是小米,29岁的技术爱好者。今天来聊聊线程和进程的区别。进程是操作系统中运行的程序实例,有独立内存空间;线程是进程内的最小执行单元,共享内存。创建进程开销大但更安全,线程轻量高效但易引发数据竞争。面试时可强调:进程是资源分配单位,线程是CPU调度单位。根据不同场景选择合适的并发模型,如高并发用线程池。希望这篇文章能帮你更好地理解并回答面试中的相关问题,祝你早日拿下心仪的offer!
21 6
|
13天前
|
监控 Java
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
65 17
|
24天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者
|
9天前
|
缓存 安全 算法
Java 多线程 面试题
Java 多线程 相关基础面试题
|
15天前
|
Java API 调度
Java 日期与时间处理:精准掌控时间流转
Java 8引入了全新的日期和时间API,解决了旧版`java.util.Date`和`Calendar`类设计不佳、操作繁琐的问题。新API包括`LocalDate`、`LocalTime`和`LocalDateTime`类,操作简洁直观,符合日常思维习惯。同时提供了`Period`和`Duration`处理时间间隔,以及`DateTimeFormatter`进行格式化输出。这些改进使开发者能更高效、准确地处理日期和时间,极大提升了开发效率与代码质量。 (239字符)
52 6
|
26天前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。
|
26天前
|
消息中间件 缓存 安全
Java多线程是什么
Java多线程简介:本文介绍了Java中常见的线程池类型,包括`newCachedThreadPool`(适用于短期异步任务)、`newFixedThreadPool`(适用于固定数量的长期任务)、`newScheduledThreadPool`(支持定时和周期性任务)以及`newSingleThreadExecutor`(保证任务顺序执行)。同时,文章还讲解了Java中的锁机制,如`synchronized`关键字、CAS操作及其实现方式,并详细描述了可重入锁`ReentrantLock`和读写锁`ReadWriteLock`的工作原理与应用场景。
|
26天前
|
监控 Java API
探索Java NIO:究竟在哪些领域能大显身手?揭秘原理、应用场景与官方示例代码
Java NIO(New IO)自Java SE 1.4引入,提供比传统IO更高效、灵活的操作,支持非阻塞IO和选择器特性,适用于高并发、高吞吐量场景。NIO的核心概念包括通道(Channel)、缓冲区(Buffer)和选择器(Selector),能实现多路复用和异步操作。其应用场景涵盖网络通信、文件操作、进程间通信及数据库操作等。NIO的优势在于提高并发性和性能,简化编程;但学习成本较高,且与传统IO存在不兼容性。尽管如此,NIO在构建高性能框架如Netty、Mina和Jetty中仍广泛应用。
37 3
|
26天前
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
52 3
|
26天前
|
安全 算法 Java
Java CAS原理和应用场景大揭秘:你掌握了吗?
CAS(Compare and Swap)是一种乐观锁机制,通过硬件指令实现原子操作,确保多线程环境下对共享变量的安全访问。它避免了传统互斥锁的性能开销和线程阻塞问题。CAS操作包含三个步骤:获取期望值、比较当前值与期望值是否相等、若相等则更新为新值。CAS广泛应用于高并发场景,如数据库事务、分布式锁、无锁数据结构等,但需注意ABA问题。Java中常用`java.util.concurrent.atomic`包下的类支持CAS操作。
62 2