java中断
理解java中断
Java中断机制是一种协作机制,即通过中断并不能直接终止另一个线程,而需要被中断的线程自己处理中断。例如,当线程t1想中断线程t2,只需要在线程t1中将线程t2对象的中断标识置为true,然后线程2可以选择在合适的时候处理该中断请求,甚至可以不理会该请求,就像这个线程没有被中断一样。
中断相关的方法:
public class Thread{
public void interrupt(){} //中断目标线程,实际上就是设置中断状态为true
public boolean isInterrupted(){} //返回目标线程的中断状态
public static boolean interrupted(){} //清除当前线程的中断状态,并返回它之前的值
}
非静态方法和静态方法的区别:
//调用native方法,判断线程是否被中断,不清除中断状态
public boolean isInterrupted() {
return isInterrupted(false);
}
//调用native方法,判断线程是否被中断,清除中断状态
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
//native方法,测试线程是否被中断。ClearInterrupted决定是否需要清除中断状态
private native boolean isInterrupted(boolean ClearInterrupted);
JVM内部确实为每个线程维护了一个中断标记。但应用程序不能直接访问这个中断变量,必须通过上面几个方法进行操作。通常情况下,调用线程的interrupt方法,并不能立即引发中断,只是设置了JVM内部的中断标记。因此,通过检查中断标记,应用程序可以做一些特殊操作,也可以完全忽略中断。
哪些场景可以用到中断?
- 如果一个方法声明抛出InterruptedException,表示该方法是可中断的。比如sleep、wait、join等。
//Thread类,native方法,当前线程休眠mills毫秒。如果其他线程中断当前线程,则当前线程抛出异常InterruptedException的时候清除当前线程的中断状态。
public static native void sleep(long millis) throws InterruptedException;
//Object类
public final native void wait(long timeout) throws InterruptedException;
public final native void notify();
public final native void notifyAll();
- 自定义的可中断方法。需要在适合处理中断的地方检测线程中断状态并处理。
if(Thread.currentThread().isInterrupted()){
//do something
}
阻塞方法怎么响应中断
- 对于自定义的可中断的方法,如上,在必要的时候,判断线程中断状态,来响应中断。当然,如果执行的时候,一直没有判断中断状态,自然也不会响应中断。
- java封装的可中断方法,sleep等,是由JVM来控制的。
一些不会抛出 InterruptedException 的线程阻塞操作
然而,对于某些线程阻塞操作,JVM并不会自动抛出InterruptedException异常。例如,某些I/O操作和内部锁操作。对于这类操作,可以用其他方式模拟中断:
- java.io中的同步IO
读写socket的时候,InputStream和OutputStream的read和write方法会阻塞等待,但不会响应java中断。不过,调用Socket的close方法后,被阻塞线程会抛出SocketException异常。 - 利用Selector实现的异步I/O
如果线程被阻塞于Selector.select(在java.nio.channels中),调用wakeup方法会引起ClosedSelectorException异常。 - 等待获取某个内置锁
如果线程在等待获取一个内部锁,我们将无法中断它。但是,利用Lock类的lockInterruptibly方法,我们可以在等待锁的同时,提供中断能力。
实战
考虑以下场景,使用线程池执行任务,任务包含一系列查询操作和一个修改操作,查询操作可能超时。每个任务的超时时间是3秒。如果FutureTask超时返回,而任务还在继续执行,就会造成数据不一致。这时候需要再查询一次任务的结果才知道执行是否成功。而如果超时之后直接查询,有可能任务还在执行中,这时查到的也是不一样的。此时,可以任务外超时处理中,取消任务;同时,任务内在合适的部分,添加是否中断的判断。如:
//任务外超时处理中,取消任务
try{
SaveResult result = task.get(3000, TimeUnit.MILLISECONDS)); //3s超时
}catch (Exception e){
if(e instanceof TimeoutException){
//超时返回,不知道结果,需要取消任务;参数true表示中断正在执行的操作
task.cancel(true);
}
}
//任务内在合适的部分,添加中断的判断和相关操作
Future<SaveResult> task = executor.submit(new Callable<SaveResult>() {
@Override
public SaveResult call() throws Exception {
//do something, 1.5s
//do others, 1.5s
//任务内,判断当前线程是否被中断,如果已经被中断,则不执行变更操作
if(!Thread.currentThread.isInterruptrf()){
//update sth
}
return result ;
}
});
看看FutureTask中cancel源码,如果需要中断,则是使用线程中断的方式
public boolean cancel(boolean mayInterruptIfRunning) {
if (state != NEW)
return false;
if (mayInterruptIfRunning) {
if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, INTERRUPTING))
return false;
Thread t = runner;
if (t != null)
t.interrupt();
UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); // final state
}
else if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, CANCELLED))
return false;
finishCompletion();
return true;
}
参考
java中断的更多相关文章
- Java 中断异常的正确处理方式
处理InterruptedException 这个故事可能很熟悉:你正在写一个测试程序,你需要暂停某个线程一段时间,所以你调用 Thread.sleep().然后编译器或 IDE 就会抱怨说 Inte ...
- java 中断线程的几种方式 interrupt()
中断 中断(Interrupt)一个线程意味着在该线程完成任务之前停止其正在进行的一切,有效地中止其当前的操作.线程是死亡.还是等待新的任务或是继续运行至下一步,就取决于这个程序.虽然初次看来它可能显 ...
- 【Java多线程】Java 中断
如何安全的结束一个正在运行的线程 java.lang.Thread类包含了一些常用的方法,如:start(), stop(), stop(Throwable) ,suspend(), destroy( ...
- Java中断异常 InterruptedException 的正确处理方式
你看到这篇文件可能是因为你已经调用了一个抛出 InterruptedException 异常的方法,并且需要以某种方式处理它. 首先,需要了解为一个方法为啥会 throws InterruptedEx ...
- Java 中断
https://zhuanlan.zhihu.com/p/45667127 看的似懂非懂
- Java 中断线程
- Java线程中断的本质深入理解(转)
一.Java中断的现象 首先,看看Thread类里的几个方法: public static boolean interrupted 测试当前线程是否已经中断.线程的中断状态 由该方法清除.换句话说,如 ...
- java线程池和中断总结
目录 java线程池和中断总结 一. 线程池的使用 二. java中断机制 中断的处理 三. 线程间通信机制总结 java线程池和中断总结 本系列文是对自己学习多线程和平时使用过程中的知识梳理,不适合 ...
- Java线程中断的本质深入理解
Java的中断是一种协作机制.也就是说调用线程对象的interrupt方法并不一定就中断了正在运行的线程,它只是要求线程自己在合适的时机中断自己. 一.Java中断的现象 首先,看看Thread类里的 ...
随机推荐
- Linux中select poll和epoll的区别
在Linux Socket服务器短编程时,为了处理大量客户的连接请求,需要使用非阻塞I/O和复用,select.poll和epoll是Linux API提供的I/O复用方式,自从Linux 2.6中加 ...
- jenkins+ant+jmeter自动化环境搭建(一)
写在最前面: jmeter:测试接口的工具,支持java语言: ant:Apache Ant是一个Java库和命令行工具,其任务是将构建文件中描述的进程作为相互 ...
- java容器类分析:Collection,List,ArrayList
1. Iterable 与 Iterator Iterable 是个接口,实现此接口使集合对象可以通过迭代器遍历自身元素. public interface Iterable<T> 修饰符 ...
- 利用 xrandr 命令修改屏幕分辨率
问题背景 电脑外接着一个 23' 的显示器,分辨率为 1920*1080. 操作系统:ubuntu 14.04 今天,通过 Setting->Displays 中选择外接屏的分辨率时,发现最大只 ...
- 质量管理:PDCA循环
PDCA循环又叫质量环,是管理学中的一个通用模型,最早由休哈特于1930年构想,后来被美国质量管理专家戴明博士在1950年再度挖掘出来,并加以广泛宣传和运用于持续改善产品质量的过程.[1] 中文名 P ...
- sublime Xdebug 配置
Sublime Text 配置x-debug 配置php 的x-debug 拓展 下载地址 :http://www.xdebug.org/download.php 放到php ext的目录下 然后使用 ...
- ios学习笔记(一)Windows7上使用VMWare搭建iPhone开发环境
我们都知道开发iPhone等ios平台的移动应用时需要使用Mac本,但是Mac本都比较昂贵,所以我们可以采用Windows7上利用VMWare安装Mac操作系统的方法来模拟ios开发环境,达到降低成本 ...
- VxWorks 引导程序
前言:vxworks 的一些文件,如 usrconfig.c 在 config,comp目录中均有出现,因编译方式而选择某一个文件,命令行方式采用 config 目录文件,tornado 图形界面配置 ...
- dojo柱形图
dojo柱形图添加属性 1.给柱状图的柱子填充颜色 .addSeries("A",[45,56,12,23,78,67],{stroke:{color:"#FF0000& ...
- Error Code: 1305. FUNCTION student.rand_string does not exist
1.错误描述 13:52:42 call new_procedure Error Code: 1305. FUNCTION student.rand_string does not exist 0.0 ...