Java中禁用Thread.stop(),因其破坏锁和状态导致数据不一致;应使用interrupt()协作中断,并在循环中检查isInterrupted()或捕获InterruptedException后退出。
stop()强行终止线程调用Thread.stop()会立即释放所有锁并破坏线程状态,极易导致数据不一致或死锁。JDK早在1.2就将其标记为@Deprecated,现代代码中绝对禁止使用。
常见错误现象包括:共享对象处于中间状态、synchronized块提前退出后锁未释放、JVM抛出ThreadDeath异常(该异常甚至无法被常规catch捕获)。
Thread.interrupt()和线程自身响应stop()在任何JDK版本(包括Java 17+)中都不应
interrupt()到底做了什么interrupt()只是设置线程的中断状态位,并不强制停掉线程。它的行为取决于线程当前所处状态:
WAITING或TIMED_WAITING(如调用wait()、join()、sleep())时,会立即抛出InterruptedException,同时清除中断状态RUNNABLE状态时,仅设置isInterrupted()返回true,不抛异常,也不影响执行流interrupt()无任何效果关键点在于:中断本身不等于停止,它只是一个信号,是否响应、如何响应,完全由线程自己决定。
典型做法是在循环中定期检查中断状态,并主动退出。重点不是“捕获InterruptedException”,而是“尊重中断意图”。
while (!Thread.currentThread().isInterrupted()) {
// 执行任务逻辑
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// 清理资源后退出循环
Thread.currentThread().interrupt(); // 恢复中断状态(可选)
break;
}
}
InterruptedException——空catch是严重错误catch块中调用Thread.currentThread().interrupt(),是为了保留中断信号供上层判断(尤其在线程池中很重要)java.nio.channels.InterruptibleChannel会在中断时关闭通道;ReentrantLock.lockInterruptibly()可响应中断finally里重置中断状态——这会掩盖真实的中断请求提交到ExecutorService的任务,其Future.cancel(true)调用的正是目标线程的interrupt(),但很多开发者误以为这能“杀掉”任务。
sleep、lockInterruptibly),cancel(true)几乎无效shutdownNow()会尝试中断所有正在运行的线程,但返回的List包含的是**尚未开始执行**的任务,不是被中断的任务CompletableFuture时,cancel(true)不会中断底层线程,只影响future的状态真正可靠的取消,必须在任务逻辑内部做检查——外部中断只是触发器,不是终止器。