Skip to content

停止运行线程

一、三种停止线程方式

  1. 自定义布尔退出标记 设置volatile布尔变量,循环内判断标记,满足条件退出run方法,线程正常结束。安全优雅,业务可控。
  2. Thread.stop()(废弃,禁止使用) 强制杀死线程,直接释放锁,会造成数据错乱、资源未释放、事务中断,JDK标记废弃。
  3. interrupt() 中断标记法(主流推荐) 仅设置线程中断状态,不会直接杀死线程,分阻塞线程运行中线程两种逻辑。

二、interrupt 详细原理

1. 核心本质

interrupt() 只是给线程打上中断标记,不会立刻终止线程,由线程自身代码判断标记自主退出。 配套方法:

  • thread.interrupt():设置中断标记为true
  • Thread.isInterrupted():获取当前线程中断标记,不清除标记
  • Thread.interrupted():静态方法,获取标记并清除中断标记

2. 两种场景处理逻辑

1)线程处于阻塞状态(sleep / wait / join) 调用interrupt后,线程立刻抛出InterruptedException,同时自动清除中断标记; 捕获异常后可主动跳出循环结束线程。

2)线程正常运行、无阻塞 interrupt仅修改中断标记为true,不会抛异常; 业务代码循环中通过isInterrupted()判断标记,主动return退出。

3. 优势

完全交给业务代码控制退出时机,能收尾资源、提交/回滚事务,不会出现stop()的数据安全问题。

三、面试高频问题解析

  1. 问:Java有哪些停止线程的方式?

    答: 三种。第一,自定义volatile布尔标识,正常走完run方法退出;第二,调用stop()强制终止,已废弃不推荐;第三,使用interrupt()设置中断标记,线程自行判断标记退出,是项目主流方案。

  2. 问:interrupt()会直接杀死线程吗?

    答: 不会。interrupt仅修改线程内部中断状态标记,不会直接终止线程;只有线程代码主动检测该标记,或线程处于sleep/wait/join阻塞时抛出异常,才能结束线程。

  3. 问:sleep的线程调用interrupt会发生什么?

    答: 线程立即退出阻塞,抛出InterruptedException,同时清空线程的中断标记,需要在catch块中手动跳出循环终止任务。

  4. 问:isInterrupted()和interrupted()有什么区别?

    答: isInterrupted()是实例方法,仅读取中断标记,不会重置状态;interrupted()是静态方法,读取标记后会把中断状态重置为false。

  5. 问:为什么不推荐使用Thread.stop()?

    答: stop会强行终止线程,不执行收尾逻辑,直接释放同步锁,极易导致共享数据损坏、文件/连接资源未关闭、事务中途中断,存在严重并发安全问题,JDK已废弃。

Powered by VitePress 1.6.4 | 持续更新中