问题

Java里一个线程调用了Thread.interrupt()到底意味着什么?

回答
在 Java 中,当一个线程调用了 `Thread.interrupt()` 方法时,这并不是像直接终止线程那样强制停止它。相反,它是一个通知机制,用于向目标线程发出一个“中断请求”。这个请求会标记目标线程为“中断状态”,并根据目标线程当前所处的状态,可能会触发一些特定的行为。

下面我将详细解释 `Thread.interrupt()` 的含义和工作原理:

1. 标记中断状态 (Setting the Interrupted Flag):

`Thread.interrupt()` 方法的核心作用是设置目标线程的内部中断标志(一个布尔值)为 `true`。
这个标志是线程对象自身的一部分。

2. 影响线程执行的关键是“响应性”:

仅仅设置中断标志本身并不会立即停止线程的执行。线程是否会因为中断而改变行为,取决于它是否“响应”了这个中断。线程响应中断主要有两种方式:

被阻塞操作打断: 如果目标线程正在执行一个阻塞操作,并且这个阻塞操作支持中断,那么当调用 `interrupt()` 时,阻塞操作会立即被中断异常(如 `InterruptedException`)打破。
常见的阻塞操作包括:
`Thread.sleep()`
`Object.wait()`
`Thread.join()`
`BlockingQueue.take()`, `BlockingQueue.poll()` (带有超时参数的也会)
`Condition.await()`
`Selector.select()`
I/O 操作(如 `InputStream.read()`, `OutputStream.write()`),尽管这些 I/O 操作是否可中断取决于具体的 JDK 实现和操作系统。
当这些操作被中断时,它们会抛出一个 `InterruptedException`。 这是线程响应中断的最直接和最常见的方式。

主动检查中断状态: 如果线程没有在执行阻塞操作,或者执行的阻塞操作不支持中断,那么它需要主动地检查自身的中断状态,然后根据这个状态来决定如何处理。
如何检查中断状态? 主要有两种方法:
`Thread.currentThread().isInterrupted()`: 这是一个非破坏性的检查。它会返回当前线程的中断状态,并且不会清除中断标志。这意味着你可以多次调用它来查看中断状态,直到它被清除。
`Thread.interrupted()`: 这是一个破坏性的检查。它会返回当前线程的中断状态,但是会同时将中断标志重置为 `false`。这意味着如果你调用 `Thread.interrupted()` 并且返回 `true`,那么之后再调用它时就会返回 `false`,除非再次被中断。

3. `InterruptedException` 的处理:

当一个阻塞操作抛出 `InterruptedException` 时,JVM 会自动将该线程的中断标志重置为 `false`。
因此,在捕获 `InterruptedException` 的 `catch` 块中,通常的做法是将中断标志重新设置回去,以便更上层的代码也能知道线程被中断了。这可以通过再次调用 `Thread.currentThread().interrupt()` 来实现。

4. `Thread.interrupt()` 的主要用途:

优雅地停止线程: `interrupt()` 是实现线程协作式终止的标准方式。线程不会被强制终止,而是有机会进行清理工作,然后自行退出。
中断阻塞操作: 强制打断正在等待的线程,例如在一个繁忙的服务器中,当一个请求不再需要时,可以中断处理该请求的线程。
实现超时机制: 在执行需要一定时间的任务时,可以设置一个定时器,当超时发生时中断执行任务的线程。

5. 举例说明:

示例 1:通过 `Thread.sleep()` 中断

```java
public class InterruptExample1 {
public static void main(String[] args) throws InterruptedException {
Thread workerThread = new Thread(() > {
try {
System.out.println("Worker thread is starting...");
// 线程执行一个可能阻塞的操作
Thread.sleep(5000); // 睡眠 5 秒
System.out.println("Worker thread finished sleeping.");
} catch (InterruptedException e) {
System.out.println("Worker thread was interrupted during sleep!");
// 捕获到中断异常,通常需要重新设置中断标志
Thread.currentThread().interrupt();
}
System.out.println("Worker thread is ending.");
});

workerThread.start();

// 让主线程等待一小段时间,确保 workerThread 已经开始执行
Thread.sleep(1000);

System.out.println("Main thread is interrupting the worker thread...");
workerThread.interrupt(); // 发出中断请求

// 等待 workerThread 终止
workerThread.join();
System.out.println("Main thread finished.");
}
}
```

输出解释:

1. `Worker thread is starting...`
2. `Main thread is interrupting the worker thread...`
3. `Worker thread was interrupted during sleep!` (因为 `Thread.sleep()` 被 `interrupt()` 打断了,并抛出 `InterruptedException`)
4. `Worker thread is ending.` (因为在 `catch` 块中,线程仍然会继续执行后面的代码,直到方法结束)

示例 2:主动检查中断状态

```java
public class InterruptExample2 {
public static void main(String[] args) throws InterruptedException {
Thread longRunningTask = new Thread(() > {
System.out.println("Long running task thread is starting...");
int count = 0;
// 循环直到被中断
while (!Thread.currentThread().isInterrupted()) {
count++;
System.out.println("Task is running, count: " + count);
// 模拟一些耗时操作,但不阻塞
try {
Thread.sleep(100); // 允许其他线程(如主线程)有机会中断
} catch (InterruptedException e) {
System.out.println("Task thread received interrupt during sleep!");
Thread.currentThread().interrupt(); // 重新设置中断标志
}
}
System.out.println("Long running task thread detected interruption. Exiting gracefully.");
// 可以在这里进行一些清理工作
});

longRunningTask.start();

// 让任务运行一段时间
Thread.sleep(500);

System.out.println("Main thread is interrupting the long running task...");
longRunningTask.interrupt(); // 发出中断请求

longRunningTask.join();
System.out.println("Main thread finished.");
}
}
```

输出解释:

1. `Long running task thread is starting...`
2. `Task is running, count: 1`
3. `Task is running, count: 2`
4. `Task is running, count: 3`
5. `Task is running, count: 4`
6. `Task is running, count: 5`
7. `Main thread is interrupting the long running task...`
8. `Long running task thread detected interruption. Exiting gracefully.` (因为 `while (!Thread.currentThread().isInterrupted())` 条件变为 `false`,循环结束)

6. 关键点总结:

`Thread.interrupt()` 是一个请求,不是命令。
线程必须主动响应中断,才能受到影响。
响应方式主要有两种:被阻塞操作抛出 `InterruptedException`,或主动检查 `isInterrupted()` 状态。
捕获 `InterruptedException` 时,通常需要重新设置中断标志。
这是实现线程协作式终止的推荐方式,比直接暴力中断(如 `Thread.stop()`,已被废弃)更安全。

理解 `Thread.interrupt()` 的核心在于它是一个合作机制。调用 `interrupt()` 的线程只是通知另一个线程“我希望你停止”,而另一个线程需要通过检查自己的状态或者等待被可中断的操作打断来做出回应。

网友意见

user avatar

首先,一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止。

所以,Thread.stop, Thread.suspend, Thread.resume 都已经被废弃了。

而 Thread.interrupt 的作用其实也不是中断线程,而是「通知线程应该中断了」,

具体到底中断还是继续运行,应该由被通知的线程自己处理。

具体来说,当对一个线程,调用 interrupt() 时,

① 如果线程处于被阻塞状态(例如处于sleep, wait, join 等状态),那么线程将立即退出被阻塞状态,并抛出一个InterruptedException异常。仅此而已。

② 如果线程处于正常活动状态,那么会将该线程的中断标志设置为 true,仅此而已。被设置中断标志的线程将继续正常运行,不受影响。

interrupt() 并不能真正的中断线程,需要被调用的线程自己进行配合才行。

也就是说,一个线程如果有被中断的需求,那么就可以这样做。

① 在正常运行任务时,经常检查本线程的中断标志位,如果被设置了中断标志就自行停止线程。

② 在调用阻塞方法时正确处理InterruptedException异常。(例如,catch异常后就结束线程。)

       Thread thread = new Thread(() -> {     while (!Thread.interrupted()) {         // do more work.     } }); thread.start();  // 一段时间以后 thread.interrupt();      

具体到你的问题,Thread.interrupted()清除标志位是为了下次继续检测标志位。

如果一个线程被设置中断标志后,选择结束线程那么自然不存在下次的问题,

而如果一个线程被设置中断标识后,进行了一些处理后选择继续进行任务,

而且这个任务也是需要被中断的,那么当然需要清除标志位了。

类似的话题

  • 回答
    在 Java 中,当一个线程调用了 `Thread.interrupt()` 方法时,这并不是像直接终止线程那样强制停止它。相反,它是一个通知机制,用于向目标线程发出一个“中断请求”。这个请求会标记目标线程为“中断状态”,并根据目标线程当前所处的状态,可能会触发一些特定的行为。下面我将详细解释 `T.............
  • 回答
    .......
  • 回答
    .......
  • 回答
    .......
  • 回答
    .......
  • 回答
    Java 平台中的 JVM (Java Virtual Machine) 和 .NET 平台下的 CLR (Common Language Runtime) 是各自平台的核心组件,负责托管和执行代码。它们都是复杂的软件系统,通常会使用多种编程语言来构建,以充分发挥不同语言的优势。下面将详细介绍 JV.............
  • 回答
    Java 官方一直以来都坚持不在函数中提供直接的“传址调用”(Pass by Address)机制,这背后有深刻的设计哲学和技术考量。理解这一点,需要从Java的核心设计理念以及它所解决的问题出发。以下是对这个问题的详细阐述: 1. Java 的核心设计理念:简洁、安全、面向对象Java 在设计之初.............
  • 回答
    Java 的 `private` 关键字:隐藏的守护者想象一下,你在经营一家精心制作的糕点店。店里最美味的招牌蛋糕,其配方是成功的关键,你自然不会轻易公开给竞争对手,对吧?你只希望自己信任的糕点师知道如何制作,并且知道在什么时候、以什么样的方式使用这些食材。这就是 `private` 关键字在 Ja.............
  • 回答
    Java 在引入泛型时,虽然极大地提升了代码的类型安全和可读性,但严格来说,它并没有实现我们通常理解的“真正意义上的”泛型(相对于一些其他语言,比如 C++ 的模板)。这其中的核心原因可以追溯到 Java 的设计理念和对向后兼容性的考量,具体可以从以下几个方面来详细阐述:1. 类型擦除 (Type .............
  • 回答
    这个问题很有意思!“360 垃圾清理”这个概念,如果用在 Java 的世界里,就好像是问:“为什么 Java 的垃圾回收机制,不像我们电脑上安装的 360 软件那样,主动去到处扫描、删除那些我们认为‘没用’的文件?”要弄明白这个,咱们得先聊聊 Java 的垃圾回收,它其实是个非常聪明且有组织的过程,.............
  • 回答
    好的,咱们来聊聊 Java 内存模型(JMM)和 Java 内存区域(Java Memory Areas)这两个既熟悉又容易混淆的概念。别担心,我会尽量用大白话讲明白,就像跟朋友聊天一样,不搞那些虚头巴脑的术语。想象一下,咱们写 Java 代码,就像是在指挥一个庞大的工厂生产零件。这个工厂有很多车间.............
  • 回答
    在 Java 泛型中,`` 和 `` 语法看起来相似,但它们代表的是截然不同的类型关系和使用场景。理解它们之间的差异,关键在于把握 Java 泛型中的“生产者消费者模型”以及它们对类型参数的“协变性”和“逆变性”的支持。我们一步一步来拆解,让你彻底明白 `super` 的含义,以及它与 `exten.............
  • 回答
    想知道 Java 学到什么程度才算精通,这确实是个挺实在的问题,也挺难有个标准答案。不过,咱可以从几个维度来聊聊,看看什么样的人,在别人看来算是玩明白了 Java。首先,得承认,所谓的“精通”这词儿,多少有点玄乎。没人敢说自己是绝对的精通,毕竟技术发展那么快,总有新鲜玩意儿冒出来。但如果说你能把 J.............
  • 回答
    作为一名Java程序员,想要在职业生涯中走得更远,确实需要掌握那些真正核心、最常用的技术。这就像学武功,要先练好基本功,才能去钻研那些花哨的招式。我个人在多年的开发实践中,总结出了一套“二八定律”式的技术认知,下面我就把这些我认为最关键的20%技术,尽可能详实地分享给大家,力求让这篇文章充满实在的干.............
  • 回答
    想要转战 Android 开发,对于 Java 的掌握程度,我更倾向于从“能解决实际问题”的角度来看待,而不是一个死板的“级别”。你想啊,我们做开发最终目的都是为了产出有价值的东西,而不是为了考一个 Java 等级证书。所以,如果非要给一个大致的界定,我认为你可以开始准备转战 Android 了,当.............
  • 回答
    好,咱就掰扯掰扯java为啥对泛型数组这事儿这么“矫情”,不直接给你整明白。这事儿啊,说起来也算是一段公案,得从java这门语言设计之初,以及它如何处理类型安全这件大事儿上头说起。核心矛盾:类型擦除与运行时类型检查的冲突你得明白java的泛型,尤其是泛型数组这块儿,最大的“绊脚石”就是它的类型擦除(.............
  • 回答
    Java 分布式应用入门指南:从零开始构建稳健的系统想要踏入 Java 分布式应用开发的大门?别担心,这并非遥不可及的挑战。相反,它是一个充满机遇和成长的领域。本文将带你系统地梳理分布式应用的核心概念,并为你推荐一系列实用的学习资料,帮助你从新手蜕变为一名合格的分布式开发者。 一、 理解分布式应用的.............
  • 回答
    JavaBean,这个在Java开发中几乎无处不在的概念,听起来可能有点“高大上”,但实际上它描述的是一种非常规整、有用的Java类。说白了,JavaBean 就是一个遵循特定规范的Java类,这个规范让它更容易被JavaBeans组件架构所识别和使用,从而方便地在可视化开发工具中进行拖放、配置和交.............
  • 回答
    Java 和 C 都是功能强大、广泛使用的面向对象编程语言,它们在很多方面都有相似之处,都是 JVM (Java Virtual Machine) 和 CLR (Common Language Runtime) 的产物,并且都拥有垃圾回收机制、强大的类库和社区支持。然而,深入探究,它们在设计理念、语.............
  • 回答
    作为一名在Java世界里摸爬滚打多年的开发者,我总会时不时地被Java的某些设计巧思所折服,同时也曾浪费过不少时间在一些细枝末节上,今天就来和大家聊聊,哪些地方是真正值得我们深入钻研的“精华”,哪些地方可能只是“旁枝末节”,不必过于纠结。 Java的“精华”:值得你投入热情和时间去领悟的部分在我看来.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有