`
jzhihui
  • 浏览: 267826 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

中断线程的执行

    博客分类:
  • Java
阅读更多

--(《Java Concurrency in Practice》读书笔记)

 

中断线程是指:线程正在运行,还没有正常退出(run方法顺利结束),而某个事件的发生导致该线程必须中断当前正在执行的任务,该线程或者退出,或者等待其它事件然后再继续执行。稳定的基于线程的服务,在程序退出时,必须能够安全的释放线程所占用的资源,减少对系统性能的影响。

 

Thread类提供的方法中与此功能相关的函数有Thread.stopThread.suspendThread.resume。但是这几个函数都不能安全的提供相应的功能:Thread.stop会导致对象处理不一致的状态,而Thread.suspendThread.resume则会导致出现死锁,具体可见API文档描述。

虽然Thread类没有一种直接又安全的机制中断线程的执行,但是却提供了一种协作机制来完成类似的功能:Thread.interrupt。但是,别误解,单纯调用这个函数并不能完成我们定义的中断线程的功能,很多时候,它只是在线程内部设置一个状态位,表示当前线程收到过interrupt请求。在解释Thread.interrupt之前,我们先看一下,如果没有相关机制的支持,我们自己怎样完成中断线程执行的功能(这里不区分RunnableThread;这个机制要正常工作,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读写相关的InputStreamOutputStreamreadwrite操作都不会interrupt请求作出响应,但是关闭底层的Socket是导致readwrite操作招聘SocketException,所以也可以作为一种中断线程的方式。

 

JDK1.5后,Java中提供java.util.concurrent包,其中包含了若干跟并发和线程管理相关的功能。ThreadPoolExecutor.submit就可以通过返回一个Future来取消或中断当前任务的执行,Future底层的实现机制也是通过Thread.interrupt来实现的。

Future.cancel只能中断对interrupt请求有响应的操作,如果阻塞的操作对interrupt请求无响应怎么办?那么可以通过重写ThreadPoolExecutor.newTaskForJDK1.6)来返回自定义的Future.cancel来实现。

当然, Thread.interrupt机制要实现类似Thread.suspendThread.resume提供的暂停和继续的语义可能比较麻烦,不过,JDK中提供了其它的一些方便的机制来完成这个目的,比如wait-and-notifyObject.waitObject.notify)或者信号量等。

分享到:
评论

相关推荐

    linux的中断线程化实现[借鉴].pdf

    在这个过程中,中断处理程序可以执行一些快速的操作,如更新统计信息,但复杂的操作会被推迟到中断线程执行。 中断线程化的主要优点包括: 1. **非阻塞**: 系统可以在中断处理期间继续处理其他任务,提高系统响应...

    java通过线程控制程序执行超时(新)

    // 超时后中断线程 } ``` 基本数据类型在超时控制中主要体现在计算或比较操作上,例如,我们可以用long类型的变量记录开始时间,然后在超时检查时与当前时间进行比较。反射则允许我们在运行时动态获取类、方法和...

    编写多线程的 Java 应用程序

    2. **抢占式线程模型**:操作系统可以随时中断线程执行,确保没有线程能长时间独占CPU。但这增加了资源管理的复杂性。 在Java中,创建线程有两种方式:一是继承Thread类,二是实现Runnable接口。线程的生命周期始于...

    Java 实例 - 中断线程源代码+详细指导教程.zip

    在Java编程中,中断线程是一项重要的任务,它允许程序在必要的时候停止或者结束一个正在运行的线程。本教程的压缩包包含了中断线程的源代码实例和详细指导,旨在帮助开发者深入理解和掌握这一核心概念。以下是关于...

    java中断线程的正确姿势完整示例.rar

    在Java编程中,中断线程是一项重要的任务,特别是在多线程环境下,我们可能需要停止某个线程的执行,以优化程序资源的使用或响应特定的系统需求。本示例将详细探讨Java中断线程的正确方法,以确保线程安全且高效地...

    多线程并发执行任务

    - **中断与守护线程**:`Thread.interrupt()`方法用于中断线程,`isInterrupted()`和`interrupted()`检查中断状态。守护线程(Daemon Thread)是一种在所有非守护线程结束时自动结束的线程,常用于后台服务。 在...

    CPU中断——实现多线程机制

    当一个线程正在执行时,如果发生了一个外部中断,操作系统会通过中断处理程序(ISR)来响应这个中断。在中断处理过程中,操作系统可能会切换到另一个线程,这样即使当前线程因为处理中断而暂停,整个程序仍然能够...

    动态控制线程执行和停止问题

    访问路径为:http://localhost:8080/web001/test.do?flag=xxyyzz&switch=off 其中switch开关参数取值有两种:on和off,on表示执行线程对应的任务,off表示中断线程正在执行的任务。

    Java基本功之中断线程的理解[参考].pdf

    Java中的线程中断是多线程编程中一个重要的概念,主要用来优雅地停止线程的执行。线程中断并不是立即终止线程,而是设置...在编写多线程代码时,应尽可能遵循中断线程的规范,以便在需要时能够有效地停止线程的执行。

    Java线程超时监控

    在Java编程中,多线程是并发执行任务的重要方式,然而在实际应用中,我们可能会遇到某些线程执行时间过长或死锁的情况,这可能导致系统资源的浪费甚至整体性能下降。因此,对线程进行超时监控是必要的,以确保程序的...

    Linux 中的各种栈:进程栈 线程栈 内核栈 中断栈

    在Linux系统中,栈可以分为进程栈、线程栈、内核栈以及中断栈。 首先,我们需要了解栈(Stack)的基本概念。栈是一种后进先出(LIFO, Last In First Out)的数据结构,它允许数据被存储和检索,但只允许在一段称为...

    易语言判断多个线程运行结束

    - 当线程执行完毕或被强制中断时,系统会自动清理线程资源。但若需手动结束线程,可使用“结束线程”命令,传入相应线程ID。 2. **线程状态查询**: - 要判断线程是否已结束,可以使用“线程状态”命令获取线程的...

    ProgressBar单独线程执行案例

    在这个"ProgressBar单独线程执行案例"中,我们将深入探讨如何在单独的线程中使用ProgressBar来避免阻塞主线程,保证界面的流畅性。 1. **线程基础**: - **主线程**:应用程序的用户界面(UI)通常运行在主线程中...

    浅析Java线程的中断机制

    Java线程的中断机制是一种优雅的终止或中断线程执行的方式,它允许线程在执行过程中响应中断请求,而不仅仅是简单地强制终止。中断机制的核心在于,它允许线程在适当的时候从阻塞状态中退出,或者在执行过程中根据...

    delphiXE多线程同步对象及异步执行.zip

    Delphi的TThread类提供了Terminate方法来请求线程停止,但线程可能正在执行一个不可中断的操作,这时就需要在线程代码中定期检查Terminated属性,以便在适当的时候退出Execute方法。 除了上述技术,还应注意线程...

    Java多线程之中断线程(Interrupt)的使用详解

    Java中的多线程允许并发执行多个任务,而中断机制是Java提供的一种优雅地停止线程执行的方式。`Thread.interrupt()`方法是中断线程的主要手段,但它的行为并不像字面意义上那样直接终止线程。相反,它通过设置线程的...

    Java中实现线程的超时中断方法实例

    1. 使用 Thread.interrupt() 方法设置线程的中断标志,但是这并不能真正中断线程,而是通知线程可以被中断。 2. 使用 ScheduledThreadPoolExecutor 来延迟执行任务,任务中执行线程的 interrupt() 方法。 使用 ...

    研讨会 硬件中断 IDLE线程设计PPT学习教案.pptx

    后台任务,如IDLE线程,是在没有硬件中断发生时执行的低优先级任务,它们负责系统的基本维护。 2. IDLE线程(IDL): IDLE线程是操作系统为处理无任务可执行情况而创建的一个特殊线程。当所有其他任务都处于等待...

    Java并发编程示例(三):线程中断

    Java并发编程中的线程中断是一个关键机制,它允许开发者在程序运行过程中显式地请求某个线程停止执行。在本示例中,我们创建了一个名为`PrimeGenerator`的线程,该线程会不断地查找并打印质数。线程中断机制的使用...

    java多线程Demo

    - interrupt()方法用于中断线程,如果线程正在阻塞(如sleep或wait),会被中断并抛出InterruptedException。 通过这些技术,我们可以构建高效、稳定、响应迅速的多线程应用程序。在实际开发中,应根据具体需求...

Global site tag (gtag.js) - Google Analytics