当前位置: 首页 > news >正文

关于 ​​Thread 与 Runnable​​ 以及 ​​线程生命周期​​ 的详细说明与示例

一、Thread 与 Runnable 的区别

1. 核心概念

​特性​​Thread​​Runnable​
​实现方式​继承 Thread 类并重写 run() 方法实现 Runnable 接口并实现 run() 方法
​灵活性​单继承限制,无法继承其他类无继承限制,可继承其他类或实现其他接口
​资源共享​每个 Thread 实例独立运行多个线程可共享同一 Runnable 实例
​推荐使用​早期 Java 版本现代 Java 开发(更灵活)

2. 代码示例

(1) 继承 Thread 类
java
复制
class MyThread extends Thread {@Overridepublic void run() {System.out.println("Thread 方式运行: " + Thread.currentThread().getName());}
}// 使用
public class Main {public static void main(String[] args) {MyThread thread = new MyThread();thread.start(); // 启动新线程(调用 run())}
}
(2) 实现 Runnable 接口
java
复制
class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("Runnable 方式运行: " + Thread.currentThread().getName());}
}// 使用
public class Main {public static void main(String[] args) {Thread thread = new Thread(new MyRunnable());thread.start(); // 启动新线程(调用 run())}
}
(3) 匿名内部类(简化写法)
java
复制
// Thread 匿名类
new Thread() {@Overridepublic void run() {System.out.println("匿名 Thread 运行");}
}.start();// Runnable 匿名类
new Thread(new Runnable() {@Overridepublic void run() {System.out.println("匿名 Runnable 运行");}
}).start();

二、线程生命周期

1. 线程状态图

复制
新建 (New) → 就绪 (Runnable) → 运行 (Running) → 终止 (Terminated)↑        ↓               ↓└阻塞 (Blocked) ←───────┘

2. 状态说明

​状态​​触发条件​​示例​
​新建 (New)​通过 new Thread() 创建线程对象Thread thread = new Thread();
​就绪 (Runnable)​调用 start() 方法后,等待 CPU 调度thread.start();
​运行 (Running)​线程获得 CPU 时间片,执行 run() 方法线程正在执行任务
​阻塞 (Blocked)​等待资源或锁(如 sleep()wait()Thread.sleep(1000);
​终止 (Terminated)​run() 方法执行完毕或线程被强制终止线程任务完成或调用 stop()(不推荐)

3. 状态转换示例

java
复制
class LifecycleDemo implements Runnable {@Overridepublic void run() {System.out.println("线程启动: " + Thread.currentThread().getName());try {// 进入阻塞状态(睡眠 2 秒)Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程终止");}
}public class Main {public static void main(String[] args) {Thread thread = new Thread(new LifecycleDemo());System.out.println("线程状态: " + thread.getState()); // NEWthread.start(); // 进入 RUNNABLESystem.out.println("线程状态: " + thread.getState()); // RUNNABLEtry {// 等待线程执行完毕thread.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("最终线程状态: " + thread.getState()); // TERMINATED}
}

三、核心方法与使用场景

1. 常用方法

​方法​​作用​​示例​
start()启动线程,JVM 调用 run() 方法thread.start();
run()线程执行体(直接调用不会启动新线程)重写 run() 方法
sleep(millis)使线程休眠指定毫秒数Thread.sleep(1000);
join()等待线程执行完毕thread.join();
currentThread()获取当前线程对象Thread.currentThread().getId();

2. 示例:线程休眠与等待

java
复制
class SleepDemo implements Runnable {@Overridepublic void run() {System.out.println("开始执行: " + Thread.currentThread().getName());try {// 休眠 1 秒Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("执行结束: " + Thread.currentThread().getName());}
}public class Main {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(new SleepDemo());thread.start();// 主线程等待子线程结束thread.join();System.out.println("主线程继续执行");}
}

四、Thread vs Runnable 最佳实践

1. 为何推荐 Runnable?

  • ​避免单继承限制​​:Java 类只能继承一个父类,使用 Runnable 可继承其他类。
  • ​资源共享​​:多个线程可共享同一 Runnable 实例,适合需要数据共享的场景。
  • ​解耦​​:将任务(Runnable)与线程(Thread)分离,提高代码灵活性。
示例:多线程共享资源
java
复制
class Counter implements Runnable {private int count = 0;@Overridepublic void run() {for (int i = 0; i < 5; i++) {count++;System.out.println(Thread.currentThread().getName() + ": " + count);}}
}public class Main {public static void main(String[] args) {Counter counter = new Counter();// 两个线程共享同一 Counter 实例Thread t1 = new Thread(counter, "线程1");Thread t2 = new Thread(counter, "线程2");t1.start();t2.start();}
}

2. Thread 的适用场景

  • 需要直接控制线程行为(如设置线程优先级、守护线程)。
  • 需要复用线程池中的线程(结合 ExecutorService)。

五、线程生命周期实战

场景:模拟订单处理流程

java
复制
class OrderProcessor implements Runnable {@Overridepublic void run() {System.out.println("订单处理开始: " + Thread.currentThread().getName());try {// 模拟耗时操作Thread.sleep(3000);} catch (InterruptedException e) {System.out.println("订单处理被中断");return; // 提前终止}System.out.println("订单处理完成: " + Thread.currentThread().getName());}
}public class Main {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(new OrderProcessor());System.out.println("线程状态: " + thread.getState()); // NEWthread.start();System.out.println("线程状态: " + thread.getState()); // RUNNABLE// 主线程等待 1 秒后中断Thread.sleep(1000);thread.interrupt(); // 发送中断信号thread.join();System.out.println("最终线程状态: " + thread.getState()); // TERMINATED}
}

六、总结

  • ​Thread 与 Runnable​​:
    • ​Runnable​​ 更灵活,推荐使用;​​Thread​​ 适合直接控制线程行为。
  • ​线程生命周期​​:
    • 重点关注 ​​新建 → 就绪 → 运行 → 终止​​,以及 ​​阻塞​​ 状态的触发条件。
  • ​核心方法​​:
    • start() 启动线程,run() 定义任务,sleep() 和 join() 控制流程。

​最佳实践​​:

  1. 优先使用 Runnable + 线程池(如 ExecutorService)。
  2. 避免直接调用 Thread.sleep() 长时间阻塞。
  3. 处理中断异常(InterruptedException),确保线程优雅退出。
http://www.xdnf.cn/news/923563.html

相关文章:

  • Protobuf 中的类型查找规则
  • ADB识别手机系统弹授权框-如何处理多重弹框叠加和重叠问题
  • 现代C++特性(一):基本数据类型扩展
  • Unity的日志管理类
  • 东芝Toshiba e-STUDIO2110AC打印机信息
  • 用电脑通过USB总线连接控制keysight示波器
  • csrf攻击学习
  • Java 8 Stream API 入门到实践详解
  • Robot Framework 一个通用的 自动化测试框架
  • 【DAY42】Grad-CAM与Hook函数
  • 大模型Agent智能体介绍和应用场景
  • SpiritTools:一款小而精的实用工具箱
  • nonlocal 与global关键字
  • BeckHoff--MES数据交互 MQ TRANCE API (MQ 追溯 API - 系统概述和命令参考)
  • YOLOv8 升级之路:主干网络嵌入 SCINet,优化黑暗环境目标检测
  • gawk 指令
  • NPOI Excel用OLE对象的形式插入文件附件以及插入图片
  • 元器件基础学习笔记——结型场效应晶体管 (JFET)
  • 实战二:开发网页端界面完成黑白视频转为彩色视频
  • 15-Oracle 23ai Vector Search Similarity Search-向量相似性和混合搜索-实操
  • Golang——10、日志处理和正则处理
  • 自制操作系统(五、重写引导部分和C语言的使用)
  • 【数据结构】详解算法复杂度:时间复杂度和空间复杂度
  • 【论文解读】DeepSeek-R1
  • 一款“短小精悍的”手机录屏软件
  • 【C++】类型转换
  • 抖音怎么下载视频?抖音怎么无水印下载别人的视频
  • 蓝凌的流程引擎队列分发器
  • Python whl安装包简介与制作完全指南
  • 【优选算法】前缀和