在现代软件开发中,并发(Concurrency)和并行(Parallelism)已成为提升程序性能、改善用户体验的关键技术。而 Java 作为一门企业级主流语言,从诞生之初就对多线程提供了强大且完善的支持。
你是否曾好奇:为什么浏览器能一边下载文件一边播放视频?为什么你的 IDE 能在后台编译代码的同时让你继续编辑?答案就是——多线程。
今天,我们就来揭开 Java 多线程的神秘面纱,从零开始理解它的基本原理、创建方式、常见问题以及最佳实践。
什么是线程?什么是多线程?
- 进程(Process):一个正在运行的程序,拥有独立的内存空间。
- 线程(Thread):进程中的一个执行单元,是 CPU 调度的基本单位。一个进程可以包含多个线程,它们共享进程的内存资源(如堆、方法区),但各自拥有独立的栈。
为什么需要多线程?
- 提高响应性:避免 GUI 程序因耗时操作而卡死(比如点击按钮后后台加载数据)。
- 提升性能:充分利用多核 CPU,加速计算密集型任务(如图像处理、大数据分析)。
- 简化建模:将复杂任务拆分为多个独立子任务,逻辑更清晰(如生产者-消费者模型)。
在 Java 中创建线程的两种方式
方式一:继承 Thread 类
class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程 " + Thread.currentThread().getName() + " 正在运行");
}
}
public class Main {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start(); // 启动线程,不要直接调用 run()
}
}
方式二:实现 Runnable 接口(推荐!)
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("线程 " + Thread.currentThread().getName() + " 正在运行");
}
}
public class Main {
public static void main(String[] args) {
Thread t = new Thread(new MyRunnable());
t.start();
}
}
线程的生命周期
Java 线程有以下几种状态(java.lang.Thread.State):
NEW:新建,尚未启动
RUNNABLE:可运行(正在运行或等待 CPU 时间片)
BLOCKED:阻塞(等待获取锁)
- WAITING:无限期等待(如调用 wait()、join())
- TIMED_WAITING:计时等待(如 sleep(1000))
- TERMINATED:已终止
线程安全与同步
当多个线程同时访问共享资源(如变量、对象)时,可能引发数据不一致问题。
示例:非线程安全的计数器
public class Counter {
private int count = 0;
public void increment() {
count++; // 实际包含读取-修改-写入三步,非原子操作!
}
public int getCount() {
return count;
}
}
结语
Java 多线程是一把“双刃剑”——用得好,程序如虎添翼;用不好,bug 难以复现、调试困难。但只要掌握基本概念、遵循最佳实践,并善用 JUC 提供的现代并发工具,你就能写出高效、稳定的并发程序。