--(《Java Concurrency in Practice》读书笔记)
中断线程是指:线程正在运行,还没有正常退出(run方法顺利结束),而某个事件的发生导致该线程必须中断当前正在执行的任务,该线程或者退出,或者等待其它事件然后再继续执行。稳定的基于线程的服务,在程序退出时,必须能够安全的释放线程所占用的资源,减少对系统性能的影响。
Thread类提供的方法中与此功能相关的函数有Thread.stop,Thread.suspend,Thread.resume。但是这几个函数都不能安全的提供相应的功能:Thread.stop会导致对象处理不一致的状态,而Thread.suspend和Thread.resume则会导致出现死锁,具体可见API文档描述。
虽然Thread类没有一种直接又安全的机制中断线程的执行,但是却提供了一种协作机制来完成类似的功能:Thread.interrupt。但是,别误解,单纯调用这个函数并不能完成我们定义的中断线程的功能,很多时候,它只是在线程内部设置一个状态位,表示当前线程收到过interrupt请求。在解释Thread.interrupt之前,我们先看一下,如果没有相关机制的支持,我们自己怎样完成中断线程执行的功能(这里不区分Runnable和Thread;这个机制要正常工作,volatile关键字不能缺):
class CancellableTask1 implements Runnable {
private volatile boolean cancelled = false;
@Override
public void run() {
while (!cancelled) {
doSomething();
}
}
public void cancel() { cancelled = true; };
}
现在考虑一个问题,如果doSomething中执行一个长时间阻塞的操作(比如sleep),那会发生什么情况?这个线程要么等待长时间(取决于阻塞操作等待的时间)后退出,要么一直不会退出(阻塞操作等待的事件没有发生)。这时候,Thread.interrupt就会发挥作用,来看一下它的API描述(原文比较详细,这里只是大致总结):
a)
如果当前线程处于阻塞状态(部分阻塞操作,一般情况下指可抛出InterruptedException的操作,如Thread.sleep),那么调用Thread.interrupt,该线程会收到一个InterruptedException,并且将当前线程的中断状态清除;
b)
如果当前线程没有阻塞,那么调用Thread.interrupt后,当前线程的中断状态被设置成true。
看描述Thread.interrupt是不能直接完成中断线程的目的,所以才说它是一种协作机制。我们来看一下这种协作机制在操作阻塞时完成中断线程的目标:
class CancellableTask2 implements Runnable {
@Override
public void run() {
try {
while (true) {
doSomething();
}
} catch (InterruptedException e) {
// Exit thread, or do something before exit.
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
public void cancel() { Thread.currentThread().interrupt();
}
这种方式下,如果有interrupt请求,线程会立即退出,当然,Thread.interrupt调用并没有强制线程一定要对interrupt请求作出响应,也可以忽略请求,继续运行(如CancellableTask3),这就取决于线程创建者采取的响应策略。只有清楚一个线程的响应策略时,才能利用Thread.interrupt机制来中断线程运行。
class CancellableTask3 implements Runnable {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
doSomething();
} catch (InterruptedException e) {
// Continue
}
}
}
public void cancel() { Thread.currentThread().interrupt(); }
}
前面说明Thread.interrupt的作用时提到,只有部分阻塞操作会对interrupt请求作出响应抛出InterruptedException,那对interrupt请求无响应的操作,该怎么处理?如跟Socket读写相关的InputStream,OutputStream的read和write操作都不会interrupt请求作出响应,但是关闭底层的Socket是导致read和write操作招聘SocketException,所以也可以作为一种中断线程的方式。
JDK1.5后,Java中提供java.util.concurrent包,其中包含了若干跟并发和线程管理相关的功能。ThreadPoolExecutor.submit就可以通过返回一个Future来取消或中断当前任务的执行,Future底层的实现机制也是通过Thread.interrupt来实现的。
Future.cancel只能中断对interrupt请求有响应的操作,如果阻塞的操作对interrupt请求无响应怎么办?那么可以通过重写ThreadPoolExecutor.newTaskFor(JDK1.6)来返回自定义的Future.cancel来实现。
当然, Thread.interrupt机制要实现类似Thread.suspend、Thread.resume提供的暂停和继续的语义可能比较麻烦,不过,JDK中提供了其它的一些方便的机制来完成这个目的,比如wait-and-notify(Object.wait和Object.notify)或者信号量等。
分享到:
相关推荐
在这个过程中,中断处理程序可以执行一些快速的操作,如更新统计信息,但复杂的操作会被推迟到中断线程执行。 中断线程化的主要优点包括: 1. **非阻塞**: 系统可以在中断处理期间继续处理其他任务,提高系统响应...
// 超时后中断线程 } ``` 基本数据类型在超时控制中主要体现在计算或比较操作上,例如,我们可以用long类型的变量记录开始时间,然后在超时检查时与当前时间进行比较。反射则允许我们在运行时动态获取类、方法和...
2. **抢占式线程模型**:操作系统可以随时中断线程执行,确保没有线程能长时间独占CPU。但这增加了资源管理的复杂性。 在Java中,创建线程有两种方式:一是继承Thread类,二是实现Runnable接口。线程的生命周期始于...
在Java编程中,中断线程是一项重要的任务,它允许程序在必要的时候停止或者结束一个正在运行的线程。本教程的压缩包包含了中断线程的源代码实例和详细指导,旨在帮助开发者深入理解和掌握这一核心概念。以下是关于...
在Java编程中,中断线程是一项重要的任务,特别是在多线程环境下,我们可能需要停止某个线程的执行,以优化程序资源的使用或响应特定的系统需求。本示例将详细探讨Java中断线程的正确方法,以确保线程安全且高效地...
- **中断与守护线程**:`Thread.interrupt()`方法用于中断线程,`isInterrupted()`和`interrupted()`检查中断状态。守护线程(Daemon Thread)是一种在所有非守护线程结束时自动结束的线程,常用于后台服务。 在...
当一个线程正在执行时,如果发生了一个外部中断,操作系统会通过中断处理程序(ISR)来响应这个中断。在中断处理过程中,操作系统可能会切换到另一个线程,这样即使当前线程因为处理中断而暂停,整个程序仍然能够...
访问路径为:http://localhost:8080/web001/test.do?flag=xxyyzz&switch=off 其中switch开关参数取值有两种:on和off,on表示执行线程对应的任务,off表示中断线程正在执行的任务。
Java中的线程中断是多线程编程中一个重要的概念,主要用来优雅地停止线程的执行。线程中断并不是立即终止线程,而是设置...在编写多线程代码时,应尽可能遵循中断线程的规范,以便在需要时能够有效地停止线程的执行。
在Java编程中,多线程是并发执行任务的重要方式,然而在实际应用中,我们可能会遇到某些线程执行时间过长或死锁的情况,这可能导致系统资源的浪费甚至整体性能下降。因此,对线程进行超时监控是必要的,以确保程序的...
在Linux系统中,栈可以分为进程栈、线程栈、内核栈以及中断栈。 首先,我们需要了解栈(Stack)的基本概念。栈是一种后进先出(LIFO, Last In First Out)的数据结构,它允许数据被存储和检索,但只允许在一段称为...
- 当线程执行完毕或被强制中断时,系统会自动清理线程资源。但若需手动结束线程,可使用“结束线程”命令,传入相应线程ID。 2. **线程状态查询**: - 要判断线程是否已结束,可以使用“线程状态”命令获取线程的...
在这个"ProgressBar单独线程执行案例"中,我们将深入探讨如何在单独的线程中使用ProgressBar来避免阻塞主线程,保证界面的流畅性。 1. **线程基础**: - **主线程**:应用程序的用户界面(UI)通常运行在主线程中...
Java线程的中断机制是一种优雅的终止或中断线程执行的方式,它允许线程在执行过程中响应中断请求,而不仅仅是简单地强制终止。中断机制的核心在于,它允许线程在适当的时候从阻塞状态中退出,或者在执行过程中根据...
Delphi的TThread类提供了Terminate方法来请求线程停止,但线程可能正在执行一个不可中断的操作,这时就需要在线程代码中定期检查Terminated属性,以便在适当的时候退出Execute方法。 除了上述技术,还应注意线程...
Java中的多线程允许并发执行多个任务,而中断机制是Java提供的一种优雅地停止线程执行的方式。`Thread.interrupt()`方法是中断线程的主要手段,但它的行为并不像字面意义上那样直接终止线程。相反,它通过设置线程的...
1. 使用 Thread.interrupt() 方法设置线程的中断标志,但是这并不能真正中断线程,而是通知线程可以被中断。 2. 使用 ScheduledThreadPoolExecutor 来延迟执行任务,任务中执行线程的 interrupt() 方法。 使用 ...
后台任务,如IDLE线程,是在没有硬件中断发生时执行的低优先级任务,它们负责系统的基本维护。 2. IDLE线程(IDL): IDLE线程是操作系统为处理无任务可执行情况而创建的一个特殊线程。当所有其他任务都处于等待...
Java并发编程中的线程中断是一个关键机制,它允许开发者在程序运行过程中显式地请求某个线程停止执行。在本示例中,我们创建了一个名为`PrimeGenerator`的线程,该线程会不断地查找并打印质数。线程中断机制的使用...
- interrupt()方法用于中断线程,如果线程正在阻塞(如sleep或wait),会被中断并抛出InterruptedException。 通过这些技术,我们可以构建高效、稳定、响应迅速的多线程应用程序。在实际开发中,应根据具体需求...