java并发编程实战学习笔记之取消与关闭

第七章 取消与关闭

7.1 任务取消

方式一、通过volatile类型的域来保存取消状态

方式二、interrupt()方法

interrupt()可以中断目标线程

isinterrupted()方法用来检测目标线程的中断状态

interrupted()用于清除中断状态,并且返回之前的中断状态,这是唯一可以清除中断状态的方法,如果在调用该方法是返回了true,那么除非你想屏蔽这个中断,否则你必须对他进行处理,可以抛出interruptExeption异常或者重新通过interrupt来恢复中断状态

sleep(),wait(),join()会在发现中断时提前返回,并且返回interruptException异常,并清除中断状态,

响应中断的方法:

  • 如果遇到的是可中断的阻塞方法抛出InterruptedException,可以继续向方法调用栈的上层抛出该异常,如果是检测到中断,则可清除中断状态并抛出InterruptedException,使当前方法也成为一个可中断的方法。
  • 若有时候不太方便在方法上抛出InterruptedException,比如要实现的某个接口中的方法签名上没有throws InterruptedException,这时就可以捕获可中断方法的InterruptedException并通过Thread.currentThread.interrupt()来重新设置中断状态。如果是检测并清除了中断状态,亦是如此。

一般的代码中,尤其是作为一个基础类库时,绝不应当吞掉中断,即捕获到InterruptedException后在catch里什么也不做,清除中断状态后又不重设中断状态也不抛出InterruptedException等。因为吞掉中断状态会导致方法调用栈的上层得不到这些信息。

当然,凡事总有例外的时候,当你完全清楚自己的方法会被谁调用,而调用者也不会因为中断被吞掉了而遇到麻烦,就可以这么做。

总得来说,就是要让方法调用栈的上层获知中断的发生。假设你写了一个类库,类库里有个方法amethod,在amethod中检测并清除了中断状态,而没有抛出InterruptedException,作为amethod的用户来说,他并不知道里面的细节,如果用户在调用amethod后也要使用中断来做些事情,那么在调用amethod之后他将永远也检测不到中断了,因为中断信息已经被amethod清除掉了。如果作为用户,遇到这样有问题的类库,又不能修改代码,那该怎么处理?只好在自己的类里设置一个自己的中断状态,在调用interrupt方法的时候,同时设置该状态,这实在是无路可走时才使用的方法。

如果任务不响应中断怎么办?    通过join设置延迟来解决。

通过future来实现取消

如何取消不可中断的阻塞?    重写interrupt方法

7.2 停止基于线程的服务

线程的停止应该由它的拥有者来执行

时间: 2024-08-07 17:11:05

java并发编程实战学习笔记之取消与关闭的相关文章

java并发编程实战学习笔记之任务执行

第六章 任务执行 6.1 在线程中执行任务 串行->多线程->有限个多线程 6.2 executor框架 通过有界队列可以防止高负荷程序过度消耗内存 java.lang.concurrent提供了线程池作为实现executor框架的一部分 executor接口:提供生产者-消费者模式 基于executor的web服务器: public class TaskExecutionWebServer {     private static final int NTHREADS = 100;     

java并发编程实战学习笔记之对象的组合与基础构建模块

第四章 对象的组合 4.1 构建安全的类 4.2 实例封闭 @ThreadSafe public class PersonSet {     @GuardedBy("this") private final Set<Person> mySet = new HashSet<Person>();     public synchronized void addPerson(Person p) {         mySet.add(p);     }     pub

java并发编程实战学习笔记之第三部分:活跃性、性能与测试

第十章 避免活跃性危险 锁顺序死锁:定义锁的顺序,可以通过某种方法决定每个锁的顺序,比如hashcode或者序列号之类的 在锁的调用顺序不是很明显的情况下,在持有锁的情况下调用其他外部方法一定要注意,可以通过开放调用,避免发生死锁的危险,即使用同步代码块保护仅仅保护那些共享变量即可,但这种降低锁粒度的方法可能会使得原本大的代码块失去原子性,解决办法为:将服务的状态改为关闭之前一直持有锁,状态改变之后,其他线程也就能够看到关闭信息从而不会再次执行关闭操作... 死锁的诊断与避免:    通过try

java并发编程实战学习笔记之基础知识与对象的共享

第二章:线程安全性 2.1 什么是线程安全性 可以被多个线程调用,并且在线程之间不会出现错误的交互 方法内的局部变量不需要保护,因为它存储在栈中,是每个线程独有的 2.2 原子性 一个共享变量可以定义为原子变量:atomic 多个共享变量时,之间可能存在某种依赖关系,分别定义为原子变量会由于竞态条件,出现错误,比如先检查后执行. 竞态条件:某个计算的正确性取决于多个线程的交替执行时序时 这就需要复合操作,将多个变量的读写操作作为一个程序块,接下来采用 2.3 加锁机制 将一个复合程序块采用内置锁

JAVA并发编程实战 读书笔记(二)对象的共享

<java并发编程实战>读书摘要 birdhack 2015年1月2日 对象的共享 JAVA并发编程实战读书笔记 我们已经知道了同步代码块和同步方法可以确保以原子的方式执行操作,但一种常见的误解是,认为关键之synchronized只能用于实现原子性或者确定临界区.同步还有另一个重要的方面:内存可见性. 1.可见性 为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制. 在没有同步的情况下,编译器.处理器以及运行时等都可能对操作的执行顺序进行一些意想不到的调整.在缺乏足够同步的多线程程

java并发编程实战学习(3)--基础构建模块

转自:java并发编程实战 5.3阻塞队列和生产者-消费者模式 BlockingQueue阻塞队列提供可阻塞的put和take方法,以及支持定时的offer和poll方法.如果队列已经满了,那么put方法将阻塞直到空间可用:如果队列为空,那么take方法将阻塞直到有元素可用.队列可以是有界的也可以是无界的. 如果生产者生成工作的速率比消费者处理工作的速率款,那么工作项会在队列中累计起来,最终好紧内存.同样,put方法的阻塞特性也极大地简化了生产者的编码.如果使用有界队列,当队列充满时,生产者将阻

《java并发编程实战》笔记(一)

最近在看<java并发编程实战>,希望自己有毅力把它读完. 线程本身有很多优势,比如可以发挥多处理器的强大能力.建模更加简单.简化异步事件的处理.使用户界面的相应更加灵敏,但是更多的需要程序猿面对的是安全性问题.看下面例子: public class UnsafeSequence { private int value; /*返回一个唯一的数值*/ public int getNext(){ return value++; } } UnsafeSequence的问题在于,如果执行时机不对,那么

《Java并发编程实战》笔记-取消与关闭

1,中断是实现取消的最合理方式.2,对中断操作的正确理解是:它并不会真正地中断一个正在运行的线程,而只是发出中断请求,然后由线程在下一个合适的时刻中断自己.3,区分任务和线程对中断的反应是很重要的4,线程有一个相应的所有者,即创建该线程的类.5,除非拥有某个线程,否则不能对该线程进行操控.由于每个线程拥有各自的中断策略,因此除非你知道中断对该线程的含义,否则就不应该中断这个线程.

JAVA并发编程实战 读书笔记(一)线程安全性

线程安全性   1.什么是线程安全 在线程安全的定义中,最核心的概念是正确性.正确性的含义是,某个类的行为与规范完全一致.当对正确性有了一个比较清晰的定义后,就可以定义线程安全性:当多个线程访问某个类时,这个类始终能表现出正确的行为,那这个类就是线程安全的. 举例:无状态对象一定是线程安全的. 大多数Servlet都是无状态的,当Servlet在处理请求时需要保存一些信息时,线程安全才会成为一个问题. 2.原子性 举个例子:语句 ++i:虽然递增操作++i是一种紧凑的语法,使其看上去是一个操作,