779 字
4 分钟
Java 线程基础:创建、状态、等待与中断

并发主线先从线程怎样执行、等待和结束开始。线程池、锁和异步框架都建立在这些基础上。

怎样创建并执行任务?#

可以继承 Thread,或向 Thread 提供 Runnable。业务通常把任务内容与线程管理分开:Runnable 没有返回值,Callable 可以返回结果并抛检查型异常,常通过 ExecutorService 提交。

Thread worker = new Thread(() -> System.out.println("running"));
worker.start();

start 让新线程参与调度并执行 run;直接调用 run 只是当前线程上的普通方法调用。同一个 Thread 对象不能重复 start。

六种线程状态#

状态含义与典型场景
NEW创建后尚未启动
RUNNABLE可运行,包括运行中或等待 CPU,也可能处于某些底层 IO 等待
BLOCKED等待进入 synchronized 的监视器锁
WAITING无超时等待,如 wait、join、park
TIMED_WAITING有超时等待,如 sleep、带超时的 wait/join
TERMINATED执行结束

这是 Java 层状态,不等于操作系统线程状态的逐项映射。ReentrantLock 竞争时可能通过 park 等待,不能统一说成 BLOCKED。

sleep、wait、join#

方法用途锁与使用要求
Thread.sleep当前线程暂停一段时间不释放已持有的监视器锁
Object.wait等待条件变化必须持有该对象监视器;等待时释放这个监视器,返回前重新获取
Thread.join当前线程等待目标线程结束用于完成协作

wait 不释放线程持有的所有其他锁。notify/notifyAll 唤醒等待线程,但不会立刻交出锁;等待线程仍需要重新竞争。

等待条件要用 while 检查,既考虑虚假唤醒,也考虑重新拿到锁时条件已被其他线程改变。

synchronized (monitor) {
while (!ready) {
monitor.wait();
}
// 使用相同锁保护下的条件
}

修改 ready 和发出通知也要遵守同一个监视器协议。

interrupt 会强制结束线程吗?#

不会,中断是协作式请求。线程需要检查中断标记,或在可中断阻塞方法中收到 InterruptedException 后进行清理和退出。

isInterrupted 查询标记而不清除;静态 Thread.interrupted 查询当前线程并清除标记。sleep/wait/join 因中断抛出 InterruptedException 时通常会清除标记。

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}

不能继续向上抛异常时,通常恢复标记并结束当前工作,不要吞掉中断。并非所有 IO 或任务都会及时响应中断,取消要看具体 API。

面试回答模板#

Runnable/Callable 定义任务,Thread 或线程池负责执行。start 启动新线程,run 是普通方法调用。BLOCKED 特指等待监视器锁。sleep 不释放锁,wait 要在同步块中调用并释放对应监视器,join 等待线程结束。interrupt 是协作式取消请求,任务必须正确处理中断。

自测#

  1. notify 后等待线程会立即运行吗?不保证,还要竞争锁并获得调度。
  2. wait 为什么放在 while 中?醒来后必须重新检查条件。
  3. 中断能让忽略中断的死循环自动退出吗?不能。
Java 线程基础:创建、状态、等待与中断
https://blog.xqcherry.top/posts/interview/java/thread-lifecycle-and-coordination/
作者
xqcherry
发布于
2026-10-12
许可协议
CC BY-NC-SA 4.0