线程基础
Java 多线程是 Java 编程中实现并发编程的核心技术,它允许程序同时执行多个任务,提高 CPU 利用率和程序性能。
基本概念
-
进程与线程
- 进程:操作系统资源分配的基本单位
- 线程:CPU 调度的基本单位,一个进程可以包含多个线程
-
线程状态
- NEW(新建)
- RUNNABLE(可运行)
- BLOCKED(阻塞)
- WAITING(等待)
- TIMED_WAITING(定时等待)
- TERMINATED(终止)
状态流转
stateDiagram-v2
[*] --> NEW
NEW --> RUNNABLE: start()
state RUNNABLE {
[*] --> READY
READY --> RUNNING: 获得CPU时间片
RUNNING --> READY: 时间片用完/yield()
}
RUNNABLE --> WAITING: wait()/join()/park()
WAITING --> RUNNABLE: notify()/notifyAll()/unpark()
RUNNABLE --> TIMED_WAITING: sleep(n)/wait(n)/join(n)
TIMED_WAITING --> RUNNABLE: 超时结束
RUNNABLE --> BLOCKED: 等待锁
BLOCKED --> RUNNABLE: 获取到锁
RUNNABLE --> TERMINATED: run()执行完成
TERMINATED --> [*]
| 转换前状态 | 触发条件 | 转换后状态 |
|---|---|---|
| NEW | 调用 start() | RUNNABLE |
| RUNNABLE | 调用 wait()/join()/LockSupport.park() | WAITING |
| RUNNABLE | 调用 sleep(n)/wait(n)/join(n) | TIMED_WAITING |
| RUNNABLE | 尝试获取锁失败 | BLOCKED |
| RUNNABLE | run()方法执行完毕 | TERMINATED |
| WAITING | notify()/notifyAll()/LockSupport.unpark() | RUNNABLE |
| TIMED_WAITING | 等待时间结束 | RUNNABLE |
| BLOCKED | 获取到锁 | RUNNABLE |
1. **RUNNABLE** 状态内部包含操作系统层面的「就绪(READY)」和「运行中(RUNNING)」两种子状态
2. 从 **BLOCKED** 状态恢复必须由其他线程释放锁
3. **TERMINATED** 是最终状态,不可逆转
4. 调用 `yield()` 只会让线程从 RUNNING 回到 READY 状态(仍属于 RUNNABLE)
常用方法
1. 线程生命周期控制
| 方法 | 所属类/接口 | 说明 | 注意事项 |
|---|---|---|---|
start() |
Thread | 启动线程,使线程进入RUNNABLE状态 | 只能调用一次,第二次调用会抛IllegalThreadStateException |
run() |
Thread/Runnable | 线程实际执行的代码 | 直接调用run()不会启动新线程 |
sleep(long millis) |
Thread | 让当前线程休眠指定毫秒数 | 不释放锁 |
yield() |
Thread | 提示调度器当前线程愿意让出CPU | 只是提示,不保证生效 |
interrupt() |
Thread | 中断目标线程 | 只是设置中断标志位,需配合isInterrupted()使用 |
isInterrupted() |
Thread | 检查线程是否被中断 | 不清除中断状态 |
interrupted() |
Thread | 检查并清除中断状态 | 静态方法,清除当前线程的中断状态 |
2. 线程同步方法
| 方法 | 所属类/接口 | 说明 | 注意事项 |
|---|---|---|---|
wait() |
Object | 释放锁并进入WAITING状态 | 必须在同步块(synchronized)中调用 |
notify() |
Object | 随机唤醒一个等待线程 | 必须在同步块中调用 |
notifyAll() |
Object | 唤醒所有等待线程 | 必须在同步块中调用 |
join() |
Thread | 等待目标线程终止 | 底层使用wait()实现 |
join(long millis) |
Thread | 限时等待线程终止 | 超时后继续执行 |
创建线程的方式
1. 继承 Thread 类
class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程运行中...");
}
}
// 使用
MyThread thread = new MyThread();
thread.start();
2. 实现 Runnable 接口
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("线程运行中...");
}
}
// 使用
Thread thread = new Thread(new MyRunnable());
thread.start();
3. 实现 Callable 接口(可返回结果)
class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
return "任务执行结果";
}
}
// 配合 Thread
Thread thread = new Thread(new FutureTask<>());
thread.start();
String result1 = thread.get(); // 获取返回结果
// 配合线程池
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new MyCallable());
String result2 = future.get(); // 获取返回结果
executor.shutdown();
4. 线程池
Java 提供了 Executor 框架来管理线程池,线程池后面说
// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(10);
// 提交任务
executor.execute(new RunnableTask());
Future<String> future = executor.submit(new CallableTask());
// 关闭线程池
executor.shutdown();

浙公网安备 33010602011771号