JJava 知识库
JAVA INTERVIEW

高频面试题

Java多线程进阶约 2 分钟

一个后台任务用 boolean 标记停止,但线上偶尔停不下来,加 volatile 能解决吗?为什么?

参考回答约 2 分钟 · 口语表达
我的判断

如果线程只是在循环中读取停止标志,volatile 能解决可见性;但任务阻塞、复合状态更新或需要清理资源时,它不够。

普通 boolean 存在数据竞争。工作线程可能一直读取寄存器或缓存里的旧值,写线程改成 false 也没有 happens-before 关系。把标志声明成 volatile 后,写入对后续读取可见,简单轮询可以停下来。

while (running) {
  doOneShortTask();
}

但我会继续看循环里做什么。如果卡在 queue.take()、网络读取或 sleep,线程根本没有机会重新读标志,这时要配合 interrupt(),并让阻塞 API 正确响应中断。退出前还要在 finally 里提交位点、关闭文件或释放锁。

volatile 也不能让 count++ 原子化,不能维护多个字段的一致状态。涉及“停止中、已停止、失败”这类状态机会用锁、CAS 或更明确的生命周期组件。