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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • python 保留小数位数不够补0_python怎么赋值

    python 保留小数位数不够补0_python怎么赋值对于python的初学者,通常情况下,只需要输出结果符合预期即可,所以通常情况下,print就能够满足需求。print但是如果对于数据流转的情况下,我一开始没有找到合适的方法:例如,我想把1.2000保留三位有效数字,如果按照其他方法:a=1.2345print(round(a,3))输出的结果是:1.234末尾有0但是如果是要将1.2000保留三位有效数字呢:a=…

    2022年8月12日
    4
  • 解决ubuntu虚拟机桥接模式下不能上网

    解决ubuntu虚拟机桥接模式下不能上网①sudovim/etc/network/interfaces修改ip和主机在同一网段,gateway和主机一致(ipconfig-all查看主机ip信息)②重启虚拟机,重启之后配置的静态ip才能生效③配置dnssudovim/etc/resolv.conf和主机一直④重启网络sudo/etc/init.d/networkingrestart…

    2022年6月9日
    63
  • 几个常用快速无损压缩算法性能比较

    几个常用快速无损压缩算法性能比较

    2022年2月23日
    52
  • Tomcat 下载安装教程

    Tomcat 下载安装教程文章目录参考资料1.下载2.安装3.卸载4启动5.关闭6.配置7.部署参考资料视频使用Tomcat的前提是你已经熟练Java,并且电脑已经安装了相应的JDK。1.下载直接从官网下载对应版本例如这边下载的是Tomcat8的windows版本:2.安装Tomcat是绿色版,直接解压即可例如在D盘的software目录下,将apache-tomcat-8.5.68-windows-x64.zip进行解压缩,会得到一个apache-tomcat-8.5.68的目录,

    2022年5月19日
    40
  • linux防cc脚本_configure命令

    linux防cc脚本_configure命令CC攻击就是说攻击者利用服务器或代理服务器指向被攻击的主机,然后模仿DDOS,和伪装方法网站,这种CC主要是用来攻击页面的,导致系统性能用完而主机挂掉了,下面我们来看linux中防CC攻击方法。什么是

    2022年8月1日
    9
  • Linux命令总结归纳

    Linux命令总结归纳Linux命令总结归纳

    2022年4月22日
    159

发表回复

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

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