核心内容摘要
3步掌握RGI:从环境搭建到抗生素抗性基因分析实战
文章目录Java线程状态图解从创建到终止的全生命周期
引言线程的重要性
线程的状态图
线程的全生命周期
创建态New
就绪态Runnable
运行态Running
阻塞态Blocked
终止态Terminated
线程状态的转换
创建态到就绪态
就绪态到运行态
运行态到阻塞态
阻塞态到就绪态
运行态到终止态
实际案例银行取款机案例背景代码实现
案例分析
六、
总结希望这篇指南能帮助你更好地理解Java中的线程状态及其转换如果你有任何问题或需要进一步的帮助请随时留言。
领取 | 1000 套高质量面试题大合集无套路闫工带你飞一把Java线程状态图解从创建到终止的全生命周期大家好我是闫工今天我们要聊一个非常重要的Java核心技术——线程的状态与生命周期。
线程是Java并发编程的基础也是面试中经常被问到的知识点。
作为一个热爱“肝”的码农我深知线程的重要性。
今天这篇文章我会用一张图来详细讲解Java线程从创建到终止的全生命周期并结合实际案例和代码示例让大家彻底搞懂线程的状态转换。
引言线程的重要性在Java中多线程编程是提升程序性能的重要手段。
通过合理利用多线程我们可以让程序同时执行多个任务充分利用 CPU 的计算能力。
比如一个Web服务器需要同时处理多个用户的请求这时候就需要用到多线程。
但是说到线程的状态很多同学可能会有点懵。
线程不是一直运行的吗为什么会有那么多状态今天我们就来详细了解一下Java线程的状态和生命周期。
线程的状态图为了让大家更直观地理解线程的状态转换我画了一张简单的状态图创建态(New) - 就绪态(Runnable) - 运行态(Running) | | ------------------------- | | 阻塞态(Blocked) 终止态(Terminated)不过这张图有点简单。
实际上Java线程的状态还有更多细节。
下面我来详细讲解每个状态。
线程的全生命周期
创建态New当用new关键字创建一个Thread对象时线程就处于“创建态”。
此时线程并没有开始运行只是一个普通的Java对象。
代码示例// 创建一个线程ThreadmyThreadnewThread(()-{System.out.println(我在跑);});此时myThread的状态是New。
注意start()方法还没调用。
就绪态Runnable当调用thread.start()方法后线程进入“就绪态”也称为可运行状态。
这并不意味着线程立即开始执行而是表示线程已经做好了运行的准备随时可能被CPU调度去执行。
代码示例// 线程处于Runnable状态myThread.start();
运行态Running当线程从就绪态被调度到CPU上开始执行时线程进入“运行态”。
此时线程正在执行run()方法中的代码。
代码示例// 线程处于Running状态publicclassMyThreadextendsThread{Overridepublicvoidrun(){System.out.println(我在跑了);}}
阻塞态Blocked当线程在运行过程中因为某些原因无法继续执行时就会进入“阻塞态”。
常见的阻塞原因包括等待用户输入比如读取键盘输入。
等待I/O操作完成比如从网络或磁盘读取数据。
等待锁释放比如在用synchronized关键字加锁的情况下。
代码示例// 阻塞态示例等待用户输入ScannerscannernewScanner(System.in);System.out.println(请输入你的名字);Stringnamescanner.nextLine();
终止态Terminated当线程完成run()方法中的所有任务后就会进入“终止态”。
此时线程已经死亡无法再被唤醒。
代码示例// 线程终止状态myThread.join();// 等待线程执行完毕System.out.println(线程已终止);
线程状态的转换
创建态到就绪态当调用start()方法时线程从创建态进入就绪态。
// 转换New - RunnableThreadmyThreadnewThread(...);myThread.start();
就绪态到运行态当线程被调度到CPU上执行时从就绪态进入运行态。
// 转换Runnable - RunningpublicclassMyThreadextendsThread{Overridepublicvoidrun(){System.out.println(我在跑了);}}
运行态到阻塞态当线程在运行过程中遇到需要等待的情况比如等待用户输入或I/O操作完成时会进入阻塞态。
// 转换Running - BlockedScannerscannernewScanner(System.in);System.out.println(请输入你的名字);Stringnamescanner.nextLine();
阻塞态到就绪态当等待的资源准备好后线程会重新回到就绪态等待被调度。
// 转换Blocked - Runnable// 用户输入完成后线程重新进入Runnable状态Stringnamescanner.nextLine();
运行态到终止态当线程完成run()方法中的所有任务后会进入终止态。
// 转换Running - TerminatedpublicclassMyThreadextendsThread{Overridepublicvoidrun(){System.out.println(我在跑了);// 任务完成线程终止}}
实际案例银行取款机为了让大家更好地理解线程的状态转换我来举一个实际的例子——银行ATM机。
案例背景假设我们有一个银行ATM机用户可以进行存款和取款操作。
每个用户的操作都需要在线程中执行。
我们需要模拟多个用户的并发操作并观察线程的状态变化。
代码实现publicclassATM{privateintbalance1000;// 初始金额publicsynchronizedvoiddeposit(intamount){System.out.println(正在存款amount);try{Thread.sleep(
;// 模拟处理时间}catch(InterruptedExceptione){e.printStackTrace();}balanceamount;System.out.println(存款完成当前余额balance);}publicsynchronizedvoidwithdraw(intamount){System.out.println(正在取款amount);try{Thread.sleep(
;// 模拟处理时间}catch(InterruptedExceptione){e.printStackTrace();}if(balanceamount){balance-amount;System.out.println(取款成功当前余额balance);}else{System.out.println(余额不足取款失败);}}publicstaticvoidmain(String[]args){ATMatmnewATM();// 创建存款线程ThreaddepositThread1newThread(()-atm.deposit(
);ThreaddepositThread2newThread(()-atm.deposit(
);// 创建取款线程ThreadwithdrawThread1newThread(()-atm.withdraw(
);ThreadwithdrawThread2newThread(()-atm.withdraw(
);// 启动所有线程depositThread
start();depositThread
start();withdrawThread
start();withdrawThread
start();// 等待所有线程完成try{depositThread
join();depositThread
join();withdrawThread
join();withdrawThread
join();}catch(InterruptedExceptione){e.printStackTrace();}}}
案例分析在这个案例中我们模拟了多个用户的并发操作创建态当线程被创建时处于创建态。
就绪态调用start()方法后线程进入就绪态等待CPU调度。
运行态当线程被调度到CPU上执行时进入运行态。
阻塞态在存款和取款操作中我们使用了synchronized关键字来确保线程安全。
当一个线程正在执行同步代码块时其他尝试访问同一资源的线程会被阻塞进入阻塞态。
终止态当线程完成任务后进入终止态。
通过这个案例我们可以清楚地看到线程在不同状态之间的转换过程。
六、
总结线程有五个基本状态创建态、就绪态、运行态、阻塞态和终止态。
线程的状态转换可以通过调用不同的方法如start()、join()来实现。
在实际开发中理解线程的状态转换对于编写高效且安全的多线程程序非常重要。
希望这篇指南能帮助你更好地理解Java中的线程状态及其转换如果你有任何问题或需要进一步的帮助请随时留言。
领取 | 1000 套高质量面试题大合集无套路闫工带你飞一把成体系的面试题无论你是大佬还是小白都需要一套JAVA体系的面试题我已经上岸了你也想上岸吗闫工精心准备了程序准备面试想系统提升技术实力闫工精心整理了1000 套涵盖前端、后端、算法、数据库、操作系统、网络、设计模式等方向的面试真题 详细解析并附赠高频考点