看完这篇,我感觉我对java多线程又懵逼了。

线程可能会阻塞或暂停执行,原因有多种:

  • 等待I/O操作结束
  • 等待获得一个锁
  • 等待从Thread.sleep方法中醒来
  • 等待另一个线程计算的结果

当线程阻塞时,它通常被挂起,并处于某种阻塞状态:

BLOCKED、WAITING或TIMED_WAITING

阻塞操作与执行时间很长的普通操作的差别在于:

被阻塞的线程必须等待某个不受它控制的事件发生后才能继续执行,例如等待I/O操作的完成,等待某个锁变成可用,或者等待外部计算的结束。

当某个外部事件发生时,线程被置回RUNNABLE状态,并可以再次被调度执行。

BlockingQueue的put和take等方法会抛出受检查异常(Checked Exception)InterruptedException,这与类库中其他一些方法的做法相同,例如Thread.sleep。当某方法抛出InterruptedException时,表示该方法是一个阻塞方法,如果这个方法被中断,那么它将努力提前结束阻塞状态。

Thread提供了interrupt方法,用于中断线程或者查询线程是否已经被中断。每个线程都有一个布尔类型的属性,表示线程的中断状态,当中断线程时将设置这个状态。

中断是一种协作机制。一个线程不能强制其他线程停止正在执行的操作而去执行其他的操作。当线程A中断B时,A仅仅是要求B在执行到某个可以暂停的地方停止正在执行的操作——前提是如果线程B愿意停止下来。虽然在API或者语言规范中并没有为中断定义任何特定应用级别的语义,但最常使用的中断情况就是取消某个操作。方法对中断请求的响应度越高,就越容易及时取消那些执行时间很长的操作。

当在代码中调用了一个将抛出InterruptedException异常的方法时,你自己的方法也就变成了一个阻塞方法,并且必须要处理对应中断响应。对于库代码来说有两种基本选择:

传递InterruptedException。

避开这个异常通常是最明智的选择——只需把InterruptedException传递给方法的调用者。传递InterruptedException的方法包括,根本不需要捕获该异常,或者捕获该异常,然后在执行某种简单的清理工作后再次抛出这个异常。

恢复中断。有时候不能抛出InterruptedException异常,例如代码是Runnable的一部分时。在这种情况下,必须捕获InterruptedException,并通过过调用当前线程上的interrupt方法恢复中断状态,这样在调用栈中更高层的代码将看到引发了一个中断。

还可以采用一些更复杂的中断处理方法,但上述两种方法已经可以应付大多数情况了。然而在出现InterruptedException时不应该做的事情是,捕获它但不做出任何响应。这将是调用栈上更高层的代码无法对中断采取处理措施,因为线程被中断的证据已经丢失。只有在一种特殊的情况中才能屏蔽中断,即对Thread进行扩展,并且能控制调用栈上所有更高层的代码。

java并发编程()阻塞方法与中断方法的更多相关文章

  1. Java并发编程-阻塞队列(BlockingQueue)的实现原理

    背景:总结JUC下面的阻塞队列的实现,很方便写生产者消费者模式. 常用操作方法 常用的实现类 ArrayBlockingQueue DelayQueue LinkedBlockingQueue Pri ...

  2. Java并发编程——阻塞队列BlockingQueue

    Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...

  3. Java并发编程的艺术(五)——中断

    什么是中断? 在Java中没有办法立即停止一条线程,然而停止线程却显得尤为重要,如取消一个耗时操作.因此,Java提供了一种用于停止线程的机制——中断. 中断只是一种协作机制,Java没有给中断增加任 ...

  4. 【Java并发编程】:线程中断

    使用interrupt()中断线程 当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返回.这 ...

  5. java并发编程阻塞队列

    在前面我们接触的队列都是非阻塞队列,比如PriorityQueue.LinkedList(LinkedList是双向链表,它实现了Dequeue接口). 使用非阻塞队列的时候有一个很大问题就是:它不会 ...

  6. Java并发编程--多线程中的join方法详解

    Java Thread中, join()方法主要是让调用该方法的thread在完成run方法里面的部分后, 再执行join()方法后面的代码 例如:定义一个People类,run方法是输出姓名年龄. ...

  7. Java并发编程-阻塞队列

    Java concurrent 包中BlockingQueue接口有ArrayBlockingqueue.LinkedBlockingQueue.PriorityBlockingQueue.Synch ...

  8. 《Java并发编程》之线程中断与终止线程运行

    Java中启动一个线程很容易,通常情况下我们都是等到任务运行结束后让线程自行停止.但有时需要在任务正在运行时取消他们,使得线程快速结束.对此Java并没有提供任何机制.但是我们可以通过Java提供的线 ...

  9. 【Java并发编程】并发编程大合集-值得收藏

    http://blog.csdn.net/ns_code/article/details/17539599这个博主的关于java并发编程系列很不错,值得收藏. 为了方便各位网友学习以及方便自己复习之用 ...

  10. 【Java并发编程】并发编程大合集

    转载自:http://blog.csdn.net/ns_code/article/details/17539599 为了方便各位网友学习以及方便自己复习之用,将Java并发编程系列内容系列内容按照由浅 ...

随机推荐

  1. OpenStack网络介绍

    OpenStack网络介绍     OpenStack里面的网络相对复杂.经常有人对几个网络概念搞混淆.因此,本文对OpenStack里面的Provider network 和 Tenant netw ...

  2. 房产地图google map的初步应用点滴.3)(转)

    房产地图google map的初步应用点滴.1)房产地图google map的初步应用点滴.2)房产地图google map的初步应用点滴.3) 房产地图google map的初步应用点滴.4) go ...

  3. 【Linux】目录权限与文件权限

    现在我们知道了Linux系统内文件的三种身份(拥有者.群组与其他人),知道每种身份都有三种权限(rwx),已知道能够使用chown, chgrp, chmod去修改这些权限与属性,当然,利用ls -l ...

  4. C# 读写网上邻居中的共享文件

    读写网上邻居共享的文件夹,和操作本地文件夹类似,只要有权限读取写入即可. 分为以下2步: 1.打通共享文件夹权限 2.操作文件 打通共享文件夹权限 /// <summary> /// 连接 ...

  5. android语音识别方法

    http://www.apkbus.com/forum.php?mod=viewthread&tid=3473 android语音识别方法一:使用intent调用语音识别程序 1. 说明 以下 ...

  6. NGUI: UIPanel控件

    转自:http://blog.csdn.net/huang9012/article/details/19411703 http://bbs.9ria.com/thread-417659-1-1.htm ...

  7. Python2 列表 cmp() 方法

    描述 Python2 列表 cmp() 方法用于比较两个列表,如果 L1 < L2 返回 -1, 如果 L1 == L2 返回 0, 如果 L1 > L2 返回 1. 语法 cmp() 方 ...

  8. vim打造开发IDE

    个人的插件和配置 set nocompatible " 去除VI一致性,必须要添加 filetype off " 必须要添加 " advanced keys " ...

  9. 禁止用户使用密码的方式登录服务器,让其使用key的方式登录

    这里我的远程登录工具xshell 所以这里我要做的是 第一步是在xshell中配置公私钥 密钥类型选择为rsa,长度为2048,并点击下一步,如下所示: 继续下一步 如果给密钥设置了密码,那么在使用这 ...

  10. 安装perl的版本控制器perlbrew

    perlbrew可以用源码方式安装perl的各种版本,可以容纳多个perl版本共存,并随意切换. 1.把perlbrew安装到home目录: curl -L https://install.perlb ...