Java 多线程基础:Thread 类核心用法详解
一、线程创建
1. 继承 Thread
类(传统写法)
class MyThread extends Thread { @Override public void run() { System.out.println("线程执行"); }
}
// 使用示例
MyThread t = new MyThread();
t.start();
缺点:Java 单继承限制,灵活性差。
2. 实现 Runnable
接口(解耦推荐)
class MyRunnable implements Runnable { @Override public void run() { System.out.println("线程执行"); }
}
// 使用示例
Thread t = new Thread(new MyRunnable());
t.start();
优点:避免单继承问题,任务与线程解耦。
3. 匿名内部类(简化写法)
(1)继承 Thread
的匿名内部类
Thread t = new Thread() { @Override public void run() { System.out.println("通过继承Thread的匿名内部类创建的线程"); }
};
t.start();
特点:
- 直接继承
Thread
,重写run()
。 - 缺点:无法再继承其他类,灵活性低。
(2)实现 Runnable
的匿名内部类
Thread t = new Thread(new Runnable() { @Override public void run() { System.out.println("通过实现Runnable的匿名内部类创建的线程"); }
});
t.start();
优点:
- 任务与线程解耦,保留继承能力。
(3)两种匿名内部类的对比
维度 | 继承 Thread 的匿名类 | 实现 Runnable 的匿名类 |
---|---|---|
继承限制 | 占用继承资格(无法继承其他类) | 无继承限制 |
代码灵活性 | 低(任务与线程绑定) | 高(任务与线程解耦) |
Lambda 支持 | 不支持(需重写 run() 方法) | 支持(Runnable 是函数式接口) |
推荐场景 | 简单的一次性任务 | 通用场景,尤其是需要解耦任务与线程时 |
4. Lambda 表达式(Java 8+ 推荐)
Thread t = new Thread(() -> System.out.println("线程执行"));
t.start();
优点:语法糖,简化 Runnable
匿名类写法。
二、线程中断
核心方法:interrupt()
Thread t = new Thread(() -> { while (!Thread.currentThread().isInterrupted()) { System.out.println("运行中"); }
});
t.start();
// 中断线程
t.interrupt();
关键点:
interrupt()
设置中断标志位,需在代码中主动检查。- 若线程在
sleep()
/wait()
中,调用interrupt()
会抛出InterruptedException
,并清空中断标志。 - 处理中断的正确姿势:
try { Thread.sleep(1000);
} catch (InterruptedException e) { // 重置中断标志或退出线程 Thread.currentThread().interrupt(); break;
}
三、线程等待
核心方法:join()
Thread t = new Thread(() -> { System.out.println("子线程执行");
});
t.start();
t.join(); // 主线程等待 t 执行完毕
System.out.println("主线程继续");
参数扩展:
join(long millis)
:最多等待指定毫秒。
适用场景:需要确保线程执行顺序(如线程B依赖线程A的结果)。
四、线程休眠
核心方法:sleep()
Thread.sleep(1000); // 休眠1秒,释放CPU
特点:
- 不释放锁(与
wait()
不同)。 - 让权:休眠期间不参与CPU调度。
五、获取线程实例
核心方法:Thread.currentThread()
Thread t = Thread.currentThread();
System.out.println("当前线程:" + t.getName());
用途:在 Runnable
任务当中获取当前线程引用。
总结
- 创建线程:优先使用
Runnable
+ Lambda。 - 中断处理:检查标志位或捕获异常,确保资源释放。
- 线程控制:
join()
协调执行顺序,sleep()
主动让权。 - 最佳实践:避免继承
Thread
,保持任务与线程解耦。
结语
多线程编程是提升程序性能的利器,但也像一把双刃剑——用得好,事半功倍;用不好,bug 丛生。通过本文,我们探讨了 Thread
类的核心用法,从线程创建、中断控制到协作与休眠,每一步都关乎程序的效率与稳定。
记住:优先选择 Runnable
** + Lambda**,让任务与线程解耦;谨慎处理线程安全,避免数据竞争的“暗坑”;善用 join()
和 sleep()
,在并发中寻求秩序。
如果你在实战中遇到过有趣的线程问题,或有更好的实践心得,欢迎在评论区分享——技术之路,唯有交流才能走得更远。🎯
愿你的代码在多线程的世界里,既快如闪电,又稳如磐石!