悠悠楠杉
Java多线程编程:Thread与Runnable深度解析
一、为什么需要多线程?
在单核CPU时代,多线程主要解决IO阻塞问题;如今多核处理器普及后,多线程成为提升程序性能的核心手段。Java从语言层面支持多线程,主要通过Thread
类和Runnable
接口实现。
二、Thread类基础用法
2.1 最简单的线程实现
java
class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程ID:" + Thread.currentThread().getId());
}
}
// 启动线程
new MyThread().start();
2.2 线程生命周期
- NEW:新建未启动
- RUNNABLE:可运行状态(包括就绪和运行中)
- BLOCKED:等待监视器锁
- WAITING:无限期等待
- TIMED_WAITING:限时等待
- TERMINATED:线程终止
三、Runnable接口详解
3.1 实现方式对比
java
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("实现Runnable的线程");
}
}
// 启动方式
new Thread(new MyRunnable()).start();
优势对比:
1. 避免单继承限制(Java不允许多重继承)
2. 更适合资源共享(多个Thread可共用同一个Runnable实例)
3. 符合面向对象设计原则(职责分离)
3.2 Lambda简化写法
java
new Thread(() -> {
System.out.println("Lambda表达式实现");
}).start();
四、实战中的注意事项
4.1 不要直接调用run()
java
// 错误示范 - 相当于普通方法调用
thread.run();
// 正确方式 - 启动新线程
thread.start();
4.2 线程安全示例
java
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
}
4.3 线程中断机制
java
Thread t = new Thread(() -> {
while(!Thread.currentThread().isInterrupted()) {
// 处理业务逻辑
}
});
t.start();
// ...
t.interrupt(); // 发出中断信号
五、两种方式的选型建议
| 场景 | 推荐方式 |
|---------------------|--------------|
| 需要继承其他类 | Runnable |
| 简单临时任务 | Thread |
| 需要共享资源 | Runnable |
| 需要线程池管理 | Runnable |
六、线程池最佳实践
java
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.execute(() -> {
// 任务代码
});
executor.shutdown();
为什么推荐线程池:
1. 降低资源消耗(复用已创建的线程)
2. 提高响应速度(无需等待线程创建)
3. 提供更强大的管理功能(任务队列、拒绝策略等)
七、常见问题排查
- 线程阻塞:检查是否有未释放的锁
- 内存泄漏:注意线程持有对象的生命周期
- 性能瓶颈:使用
jstack
工具分析线程状态