引言:
你可能听说过线程是 Java 并发编程的基础,但觉得很复杂?别怕!今天我们从最简单的概念讲起,用生活化的语言、清晰的图示和小任务带你一步步掌握线程的基础操作。读完这篇文章,你不仅会写线程代码,还能自信跟别人说:“线程?小意思!”
内容导航
- 线程是什么?
- 线程的状态
- 线程的常用方法
- 3.1 获取当前线程
- 3.2 设置线程名称
- 3.3 设置线程优先级
- 3.4 线程的让步
- 3.5 线程的休眠
- 3.6 守护线程
- 3.7 等待和唤醒
- 线程的结束方式
- 小白常见问题解答
- 总结与练习
如果你觉得这篇文章有帮助,记得点赞👍 + 收藏📂 + 关注✨,让我们一起成为线程高手!
1. 线程是什么?
我们先用一个简单的比喻来理解线程:
线程就像餐厅的服务员,程序中的任务是“客人”。
- 单线程: 一个服务员同时服务一个客人(任务必须排队完成)。
- 多线程: 多个服务员同时服务多个客人(任务并行处理,效率更高)。
- 守护线程: 像后厨的工作人员,默默保障主线程的任务运行,主线程结束后,他们自动离开。
通过线程,我们可以让程序像一个高效的餐厅,同时完成多个任务!
2. 线程的状态
Java 中,线程的生命周期包含以下 6 种状态:
状态 | 描述 | 类比 |
---|---|---|
NEW | 线程对象被创建,还未启动 | 刚入职的服务员,还没开始工作 |
RUNNABLE | 线程处于运行或就绪状态 | 服务员准备或者正在工作 |
Timed_Wating | 线程调用 sleep 或者join 方法 | 睡觉去了 |
BLOCKED | 线程等待获取锁 | 被其他服务员挡住了,不能工作 |
WAITING | 线程无限期等待,直到被唤醒 | 等待厨师通知菜已准备好 |
TERMINATED | 线程运行结束,生命周期完成 | 服务员下班回家 |
状态图解
以下是线程状态的生命周期图,用一个简单的流程帮你理清线程状态的变化:
NEW → RUNNABLE → WAITING/BLOCKED/TIMED_WAITING → TERMINATED
代码示例:查看线程状态
public class ThreadStateExample {
public static void main(String[] args) {
Thread thread = new Thread(() -> System.out.println("线程正在运行..."));
System.out.println("线程状态:" + thread.getState()); // NEW
thread.start();
System.out.println("线程状态:" + thread.getState()); // RUNNABLE
}
}
3. 线程的常用方法
以下是线程最常用的操作方法,每个方法都附带例子和注意事项!
3.1 获取当前线程
方法:
Thread.currentThread();
示例:
public class CurrentThreadExample {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("当前线程:" + Thread.currentThread().getName());
});
thread.start();
}
}
3.2 设置线程名称
方法:
Thread.setName("线程名称");
Thread.getName();
示例:
Thread thread = new Thread(() -> {
System.out.println("线程名称:" + Thread.currentThread().getName());
});
thread.setName("MyThread");
thread.start();
3.3 设置线程优先级
方法:
Thread.setPriority(int priority);
优先级范围 | 描述 |
---|---|
1 | 最低优先级 |
5 | 默认优先级 |
10 | 最高优先级 |
注意: 优先级只是建议,实际调度依赖操作系统。
3.4 线程的让步
方法:
Thread.yield();
作用: 让当前线程主动暂停,回到 RUNNABLE
状态,调度器重新选择线程执行。
3.5 守护线程
方法:
Thread.setDaemon(true);
特点: 主线程结束后,守护线程会自动退出,适合做后台任务。
示例:
Thread thread = new Thread(() -> {
while (true) {
System.out.println("守护线程运行中...");
}
});
thread.setDaemon(true);
thread.start();
3.6 等待和唤醒
方法:
wait();
notify();
notifyAll();
示例:生产者消费者模型
public class WaitNotifyExample {
public static void main(String[] args) {
Object lock = new Object();
Thread producer = new Thread(() -> {
synchronized (lock) {
System.out.println("生产者生产数据...");
lock.notify();
}
});
Thread consumer = new Thread(() -> {
synchronized (lock) {
try {
lock.wait();
System.out.println("消费者消费数据...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
consumer.start();
producer.start();
}
}
4. 线程的结束方式
方式 | 描述 | 注意 |
---|---|---|
stop() | 强制终止线程(已过时,不推荐使用) | 会导致资源未释放,慎用 |
共享变量 | 用标志位控制线程结束 | 需用 volatile 保证可见性 |
interrupt() | 设置中断标志位,线程自行结束 | 推荐使用,最安全的方式 |
示例:用 interrupt 结束线程
public class InterruptExample {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("线程运行中...");
}
System.out.println("线程被中断,结束");
});
thread.start();
Thread.sleep(2000);
thread.interrupt(); // 中断线程
}
}
5. 小白常见问题解答
Q1:
sleep()
和wait()
有什么区别?
sleep()
是让线程休眠指定时间,不释放锁。wait()
是让线程进入等待状态,并释放锁,需用notify()
唤醒。
Q2:线程的优先级真的有用吗?
- 不一定,线程优先级只是建议,操作系统可能会忽略。
Q3:守护线程会主动结束吗?
- 是的,当所有用户线程结束后,守护线程会自动退出。
6. 总结与练习
总结
- 线程的状态: 了解线程生命周期和状态切换是使用线程的基础。
- 常用方法: 掌握线程的名称、优先级、休眠和让步操作。
- 安全结束: 推荐使用
interrupt()
方式优雅终止线程。
练习任务
创建一个线程,每隔 1 秒输出 “我还在运行”,运行 5 秒后自动结束。提示:可以用
sleep()
和interrupt()
实现。
完成后记得在评论区分享代码,我会帮你检查哦!
最后的话
觉得有帮助吗?
- 点个赞👍: 鼓励作者持续创作!
- 收藏📂: 方便下次复习!
- 关注✨: 学习更多并发编程技巧!
有任何问题或者困惑,欢迎在评论区留言,我会逐一解答! 🎉