java的中断机制_java中断机制

一、导言

线程A对线程B发出建议: 你好,可以停止了哟~

在实际生产环境中,对于阻塞任务,可能存在一些情况导致阻塞任务取消、终止,例如: 计时器到期,I/O 完成,或者另一个线程的动作(释放一个锁,设置一个标志,或者将一个任务放在一个工作队列中)。这种情况下可以使用java的中断机制来进行线程间通信。

java线程中断的实现是基于一个称为中断状态的内部标志位来实现的,其中断的含义更像是建议,一个线程如何响应另一个线程的中断完全取决于程序员: 继续向上抛出、封装后抛出、中断状态复原、忽略等。java库中的许多抛出 InterruptedException 的方法(例如 sleep)都被设计为取消当前操作并在接收到中断时立即返回。

InterruptException异常就像是一个声明,声明抛出该异常的方法都可被中断,比如wait、sleep、join。异常都是由可中断方法自己抛出来的,并不是直接由interrupt()方法直接引起的。一般来说,任何通过抛出一个 InterruptedException 来退出的方法都应该清除中断状态。

二、java 中断api

interrupt()

interrupt()方法本质上就是通过调用java.lang.Thread#interrupt0设置中断flag为true,如下代码演示了该方法的使用: 另启一个线程中断了当前线程。

@Test

public void interruptSt() {

Thread mainThread = Thread.currentThread();

new Thread(/*将当前线程中断*/mainThread::interrupt).start();

try {

//public static native void sleep(long millis) throws InterruptedException;

Thread.sleep(1_000);

} catch (InterruptedException e) {

System.out.println("main 线程被中断了");

}

/*

* 输出: main 线程被中断了

*/

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

interrupted()和isInterrupted()

在说这两个方法之前先说下private native boolean isInterrupted(boolean ClearInterrupted)这个方法,interrupted()和isInterrupted()方法本质上都是调用该方法。

public boolean isInterrupted() {

// 设置this线程的中断flag,不会重置中断flag为true

return isInterrupted(false);

}

public /*静态方法*/static boolean interrupted() {

// 设置当前线程的中断flag,重置中断flag为true

return currentThread().isInterrupted(true);

}

1

2

3

4

5

6

7

8

使用示例

@Test

public void test_Flag() {

Thread currentThread = Thread.currentThread();

currentThread.interrupt();

System.out.println("当前线程状态 =" + currentThread.isInterrupted());

System.out.println("当前线程状态 =" + Thread.interrupted());

System.out.println("当前线程状态 =" + Thread.interrupted());

/* 输出

当前线程状态 =true

当前线程状态 =true

当前线程状态 =false*/

}

1

2

3

4

5

6

7

8

9

10

11

12

三、如何响应中断?

调用一个可中断的阻塞方法时需要处理受检异常InterruptException,一般来说最容易的方式就是继续抛出InterruptException ,让调用方决定对中断事件作出什么应对。但是对于一些不能在方法头直接添加异常声明的,可以catch出后再进行一些操作,例如使用Runnable时:

49ccfde4c8884222ebbf18109978c4c4.png

一般来说当catch到中断时,应该对中断状态进行还原: 调用Thread.currentThread().interrupt();,除非明确自己的操作不会丢失线程中断的证据,从而剥夺了上层栈的代码处理中断的机会。

四、总结

对目标线程调用interrupt()方法可以请求中断一个线程,目标线程通过检测isInterrupted()标志获取自身是否已中断。如果目标线程处于阻塞状态,该线程会捕获到InterruptedException。

一般来说不要catchInterruptException后不做处理(“生吞中断”)。

五、参考文章

358ab3c7999dfd4a38caa6567a620c2c.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值