interrupt interrupted_interrupt的用法

interrupt interrupted_interrupt的用法(一).关于interrupt()    interrupt()并不直接中断线程,而是设定一个中断标识,然后由程序进行中断检查,确定是否中断。    1.sleep()&interrupt()    线程A正在使用sleep()暂停着:Thread.sleep(100000);    如果要取消他的等待状态,可以在正在执行的线程里(比如这里是B)调用a.interr

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

(一).关于interrupt()
 
 
 
 interrupt()并不直接中断线程,而是设定一个中断标识,然后由程序进行中断检查,确定是否中断。
 
 
 
 1. sleep() & interrupt()

 
 
 
 线程A正在使用sleep()暂停着: Thread.sleep(100000);

 
 
 
 如果要取消他的等待状态,可以在正在执行的线程里(比如这里是B)调用a.interrupt();

 
 
 
 令线程A放弃睡眠操作,这里a是线程A对应到的Thread实例执行interrupt()时,并不需要获取Thread实例的锁定.任何线程在任何时刻,都可以调用其他线程interrupt().当sleep中的线程被调用interrupt()时,就会放弃暂停的状态.并抛出InterruptedException.丢出异常的,是A线程.
2. wait() & interrupt()

 
 
 
 线程A调用了wait()进入了等待状态,也可以用interrupt()取消.

 
 
 
 不过这时候要小心锁定的问题.线程在进入等待区,会把锁定解除,当对等待中的线程调用interrupt()时(注意是等待的线程调用其自己的interrupt()),会先重新获取锁定,再抛出异常.在获取锁定之前,是无法抛出异常的.
3. join() & interrupt()

 
 
 
 当线程以join()等待其他线程结束时,一样可以使用interrupt()取消之.因为调用join()不需要获取锁定,故与sleep()时一样,会马上跳到catch块里. 注意是随调用interrupt()方法,一定是阻塞的线程来调用其自己的interrupt方法.如在线程a中调用来线程t.join().则a会等t执行完后在执行t.join后的代码,当在线程b中调用来a.interrupt()方法,则会抛出InterruptedException
4. interrupt()只是改变中断状态而已

 
 
 
 interrupt()不会中断一个正在运行的线程。这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。

 
 
 
 如果线程没有被阻塞,这时调用interrupt()将不起作用;否则,线程就将得到异常(该线程必须事先预备好处理此状况),接着逃离阻塞状态。

 
 
 
 线程A在执行sleep,wait,join时,线程B调用A的interrupt方法,的确这一个时候A会有InterruptedException异常抛出来.但这其实是在sleep,wait,join这些方法内部会不断检查中断状态的值,而自己抛出的InterruptedException。

 
 
 
 如果线程A正在执行一些指定的操作时如赋值,for,while,if,调用方法等,都不会去检查中断状态,所以线程A不会抛出InterruptedException,而会一直执行着自己的操作.当线程A终于执行到wait(),sleep(),join()时,才马上会抛出InterruptedException.

 
 
 
 若没有调用sleep(),wait(),join()这些方法,或是没有在线程里自己检查中断状态自己抛出InterruptedException的话,那InterruptedException是不会被抛出来的. 
 
 
 
(二)Java线程中断的本质和编程原则

 
 
 
 在历史上,Java试图提供过抢占式限制中断,但问题多多,例如前文介绍的已被废弃的Thread.stop、Thread.suspend和 Thread.resume等。另一方面,出于Java应用代码的健壮性的考虑,降低了编程门槛,减少不清楚底层机制的程序员无意破坏系统的概率。
 
 
 
 如今,Java的线程调度不提供抢占式中断,而采用协作式的中断。其实,协作式的中断,原理很简单,就是轮询某个表示中断的标记,我们在任何普通代码的中都可以实现。 例如下面的代码:
 
 
 
 volatile bool isInterrupted;
 
 
 
 //…
 
 
 
 while(!isInterrupted) {
 
 
 
 
 
 
 
 compute();
 
 
 
 }
 
 
 
 但是,上述的代码问题也很明显。当compute执行时间比较长时,中断无法及时被响应。另一方面,利用轮询检查标志变量的方式,想要中断wait和sleep等线程阻塞操作也束手无策。
 
 
 
 如果仍然利用上面的思路,要想让中断及时被响应,必须在虚拟机底层进行线程调度的对标记变量进行检查。是的,JVM中确实是这样做的。下面摘自java.lang.Thread的源代码:
 
 
 
 
 
 
 
 public static boolean interrupted() {

 
 
 
 
 
 
 
 
 
 
 
 return currentThread().isInterrupted(true);

 
 
 
 
 
 
 
 }
 
 
 
 
 
 
 //…
 
 
 
 
 
 
 
 private native boolean isInterrupted(boolean ClearInterrupted);
 
 
 
 可以发现,isInterrupted被声明为native方法,取决于JVM底层的实现。
 
 
 
 实际上,JVM内部确实为每个线程维护了一个中断标记。但应用程序不能直接访问这个中断变量,必须通过下面几个方法进行操作:

 
 
 
 public class Thread {

 
 
 
 
 
 
 
 //设置中断标记

 
 
 
 
 
 
 
 public void interrupt() { … } 


 
 
 
 
 
 
 
 //获取中断标记的值

 
 
 
 
 
 
 
 public boolean isInterrupted() { … }

 
 
 
 
 
 
 
 //清除中断标记,并返回上一次中断标记的值

 
 
 
 
 
 
 
 public static boolean interrupted() { … } 
 


 
 
 
 
 
 
 
 …

 
 
 
 }
 
 
 
 通常情况下,调用线程的interrupt方法,并不能立即引发中断,只是设置了JVM内部的中断标记。因此,通过检查中断标记,应用程序可以做一些特殊操作,也可以完全忽略中断。

 
 
 
 你可能想,如果JVM只提供了这种简陋的中断机制,那和应用程序自己定义中断变量并轮询的方法相比,基本也没有什么优势。

 
 
 
 JVM内部中断变量的主要优势,就是对于某些情况,提供了模拟自动“中断陷入”的机制。

 
 
 
 在执行涉及线程调度的阻塞调用时(例如wait、sleep和join),如果发生中断,被阻塞线程会“尽可能快的”抛出InterruptedException。因此,我们就可以用下面的代码框架来处理线程阻塞中断:

 
 
 
 try {

 
 
 
 
 
 
 
 //wait、sleep或join
 
 
 
 
 
 
 }

 
 
 
 catch(InterruptedException e) {

 
 
 
 
 
 
 
 //某些中断处理工作 
 
 
 
 
 
 }

 
 
 
 所谓“尽可能快”,我猜测JVM就是在线程调度调度的间隙检查中断变量,速度取决于JVM的实现和硬件的性能。 
 
 
 
 
 
 然而,对于某些线程阻塞操作,JVM并不会自动抛出InterruptedException异常。例如,某些I/O操作和内部锁操作。对于这类操作,可以用其他方式模拟中断:

 
 
 
 1)java.io中的异步socket I/O

 
 
 
 读写socket的时候,InputStream和OutputStream的read和write方法会阻塞等待,但不会响应java中断。不过,调用Socket的close方法后,被阻塞线程会抛出SocketException异常。

 
 
 
 2)利用Selector实现的异步I/O

 
 
 
 如果线程被阻塞于Selector.select(在java.nio.channels中),调用wakeup方法会引起ClosedSelectorException异常。

 
 
 
 3)锁获取

 
 
 
 如果线程在等待获取一个内部锁,我们将无法中断它。但是,利用Lock类的lockInterruptibly方法,我们可以在等待锁的同时,提供中断能力。

 
 
 
 另外,在任务与线程分离的框架中,任务通常并不知道自身会被哪个线程调用,也就不知道调用线程处理中断的策略。所以,在任务设置了线程中断标记后,并不能确保任务会被取消。因此,有以下两条编程原则:

 
 
 
 
1)除非你知道线程的中断策略,否则不应该中断它。

 
 
 
 
 
 
 
 这条原则告诉我们,不应该直接调用Executer之类框架中线程的interrupt方法,应该利用诸如Future.cancel的方法来取消任务。


    2)任务代码不该猜测中断对执行线程的含义。

 
 
 
 
 
 
 
 这条原则告诉我们,一般代码遇在到InterruptedException异常时,不应该将其捕获后“吞掉”,而应该继续向上层代码抛出。

 
 
 
 总之,Java中的非抢占式中断机制,要求我们必须改变传统的抢占式中断思路,在理解其本质的基础上,采用相应的原则和模式来编程。
 
(三) interrupt() 与 cancel()的区别
 
 
 两者实际上都是中断线程,但是后者更安全、有条理和高效,其原因跟推荐使用
Executor而不直接使用Thread类是一致的。所以结合上面讲到的原则,我们应尽量采用cancel()方法,调用线程管理器ExecutorService接口的
submit
(
Runnable
 task) 
方法会返回一个Future<?>对象,然后调用Future.cancel()的方法来取消任务,并返回一个boolean值。

原网址:http://blog.sina.com.cn/s/blog_00ccd2400100nq7o.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/214255.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • bitblt函数_统计参数的含义

    bitblt函数_统计参数的含义【转载请注明出处: http://blog.csdn.net/lzl124631x】接口BOOLBitBlt( _In_ HDChdcDest, _In_ intnXDest, _In_ intnYDest, _In_ intnWidth, _In_ intnHeight, _In_ HDChdcSrc, _I

    2022年10月19日
    4
  • 移动通信概述-架构篇[通俗易懂]

    移动通信概述-架构篇[通俗易懂]移动通信概述-架构篇

    2022年9月21日
    3
  • 基于51单片机控制步进电机正反转

    基于51单片机控制步进电机正反转基于51单片机控制步进电机正反转此次采用uln2003模块来链接步进电机;##步进电机工作原理步进电机是一种将电脉冲信号转换成相应角位移或线位移的电动机。每输入一个脉冲信号,转子就转动一个角度或前进一步,其输出的角位移或线位移与输入的脉冲数成正比,转速与脉冲频率成正比。步进电动机的结构形式和分类方法较多,一般按励磁方式分为磁阻式、永磁式和混磁式三种;按相数可分为单相、两相、三相和多相等形式。因此我们可以控制单片机I/O口的电平来控制步进电机,此次设计中采用四相单拍工作方式,在这种工作方式下,A、

    2022年5月31日
    72
  • Java中 3*0.1 == 0.3 返回值 false ,1*0.3 == 0.3 返回值 true

    Java中 3*0.1 == 0.3 返回值 false ,1*0.3 == 0.3 返回值 trueJava中 3*0.1 == 0.3 返回值 false ,1*0.3 == 0.3 返回值 true

    2022年4月23日
    41
  • 老庄结构设计官网_互联网颗粒度的名词解释

    老庄结构设计官网_互联网颗粒度的名词解释    本文是对上篇MGN论文阅读做一个详细的补充,主要补充其结构设计及技术实现细节。文章内容整合来自云从科技资深算法研究员袁余锋老师,通过以下四个方面来讲解本次课题:1、ReID的定义及技术难点;2、常用数据集与评价指标简介;3、多粒度网络(MGN)的结构设计与技术实现;4、ReID在行人跟踪中的应用分析与技术展望ReID是行人智能认知的其中一个研究方向,行人智能认知是人脸识别之后比较重要…

    2022年10月6日
    4
  • Pycharm中安装Pygame方法「建议收藏」

    Pycharm中安装Pygame方法「建议收藏」本文转自:https://blog.csdn.net/zhangffyy/article/details/78524592第一步:打开Pycharm第二步:点File-&amp;amp;amp;gt;DefaultSettings-&amp;amp;amp;gt;ProjectInterpreter-&amp;amp;amp;gt;点加号第三步:搜索Pygame-&amp;amp;amp;gt;InstallPackage然后就安装好了,新建一个p

    2022年8月29日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号