一文读懂线程中断interrupt

前言

在网上看了几篇关于线程中断三个方法的相关文章,写的都很官方,对于初学者来说,不易理解透彻,于是决定把自己的探索结果和学习总结分享给大家。本次探索过程使用的jdk本版为:1.8.0_171。

java中的线程中断是什么?

  • 错误理解: 线程中断,从字面上来理解,第一感觉就是线程中断了,停止运行了,这是错误的理解哈。
  • 通俗正确理解: 线程中断可以理解为,它是线程对象的一个属性,key为线程中断状态,value为true or false,默认值为false,是线程通信的手段之一。
  • jdk创作者设计它的初衷 是为了提供一种手段给基于jdk编程的程序员,可用于解决在线程相互调用过程中,可能会出现线程阻塞或死锁而导致程序长时间或永久无法运行的故障。

线程中断的三个方法

线程中断状态值默认返回false,如果被中断则状态值为true,未被中断则值为false,中断状态被清除则值为false。以下表格备注列为常用的描述,具体参见jdk方法注释文档

方法名方法描述备注
public void interrupt()中断此线程如果在调用Object类的wait(),wait(long)或wait(long,int)方法或join(),join(long),join(long,int)方法时阻塞了此线程,sleep(long)或sleep(long,int)此类的方法,则其中断状态将被清除,并将收到InterruptedException
public boolean isInterrupted()测试此线程是否已被中断线程的中断状态不受此方法的影响
public static boolean interrupted()测试当前线程是否已被中断通过此方法可以清除线程的中断状态。 换句话说,如果要连续调用此方法两次,则第二次调用将返回false(除非当前线程在第一次调用清除其中断状态之后且在第二次调用检查其状态之前再次中断)

总结
一个静态方法: interrupted()
两个成员方法: isInterrupted(),interrupt()

一个用于线程通信: interrupt(),A线程想向B线程发起中断通知new B().interrupt()
两个用于获取线程中断状态值: interrupted(),isInterrupted()。前者为当前线程感知自身的中断状态Thread.interrupted(),并立即设置自身中断状态值为false;后者为A线程想感知B线程的中断状态,在A线程中调用代码new B().isInterrupted(),不改变B的中断状态。

使用场景

结束线程的三种方法(非循环代码,执行完自动结束,此处介绍需要使用循环来处理的多线程场景,如监听程序等等):

  1. 设置退出标识boolean,配合volatile 关键字
public class ThreadFlag extends Thread {
	public volatile boolean exit = false;

	public void run() {
		while (!exit);
	}

	public static void main(String[] args) throws Exception {
		ThreadFlag thread = new ThreadFlag();
		thread.start();
		sleep(5000);
		//设置退出标识
		thread.exit = true;
		thread.join();
		System.out.println("线程退出!");
	}
}
  1. 使用stop()方法,不推荐
  2. 使用线程中断,小编最推荐的一种方式(下面示例为阻塞线程的终止,非阻塞线程的终止,无需catch中的处理即可)
public class InterruptTest extends Thread{

	@Override
	public void run() {
		//线程中断状态值默认为false,此线程一开始是可以进入while执行的
		while(!isInterrupted()) {
			try {
				sleep(500);
			} catch (InterruptedException e) {
				//如果发生线程中断异常,此线程的中断状态被清除,为false,while循环还会继续执行
				System.out.println(Thread.currentThread().getName() + ":发生中断异常后,中断状态为:" + isInterrupted());
				e.printStackTrace();
				//发生中断异常,应该结束掉该线程,结束while循环即可。
				//中断自身线程操作,不可使用静态interrupted方法,否则中断状态值仍未false,无法结束。应该使用interrupt方法
				interrupt();
				System.out.println(Thread.currentThread().getName() + ":发生中断异常且调用interrupt()后,中断状态为:" + isInterrupted());
			}
		}
		System.out.println(Thread.currentThread().getName() + "线程结束");
	}
	
	public static void main(String[] args) {
		Thread thread = new InterruptTest();
		thread.setName("测试线程中断使用场景的线程");
		thread.start();
		try {
			//主线程休眠
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		thread.interrupt();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值