Java多线程——如何中断线程

本文详细解析了Java多线程中如何中断线程,重点介绍了interrupt(), interrupted()和isInterrupted()这三个函数的作用。通过示例说明了在执行状态和阻塞状态(如sleep())下,线程中断的不同处理方式,强调了中断标志位在中断机制中的关键角色。" 84808981,8141697,Spring JMS消息接收方式详解,"['Spring框架', '消息队列', 'JMS', '事务处理']
摘要由CSDN通过智能技术生成

在讲解中断线程之前,需要了解一下三个函数的具体作用

1. interrupt(): interrupt的字面意思就是中断的意思,所以对不太了解Java多线程编程的同学来说,很容易误解直接调用该函数实现线程中断,其实这个函数的真正含义并非如此,它并不能马上停止线程的执行。线程调用此方法仅仅是将该线程的中断标志位设为true(默认为false),所以总的来说该函数的主要作用就是产生中断信号,设置中断标志。当程序检测到该线程的中断标志为true,采取何种操作,不管是中断还是继续运行,都有编码的人自己实现。

2. interrupted():检测当前线程是否为中断状态,该方法具有清除中断标志位为false的功能,即执行完该方法,线程的中断标志位会被置为false。查看该方法的 定义public static boolean interrupted()可知该方法为一个静态方法。

3. isInterrupted(): 此方法与interrupted的大体功能类似,可以测试线程Thread对象是否是中断状态,但有一点不同就是该方法不能清除中断状态标志。该方法的声明如下public boolean isInterrupted(),可以看到此方法不是一个静态方法。

了解了上述三个函数的作用,可以用如下的方法来完成线程的中断了。在线程执行或者处于阻塞状态时,检测中断标志位,如果标志位为true,抛出异常执行中断操作。在实现过程中对于处于执行状态和阻塞状态的线程其实是不同的,对于处于执行状态的线程,在检测到中断标志为true时,需要手动抛出InterruptedException,而处于阻塞状态的sleep(),wait()和join()则不需要,当检测到中断标志为true,会自动抛出InterruptedException。下面的两个例子分别展示了这两种情况。

执行状态的线程中断:

public class MyThread extends Thread{
	
	@Override
	public void run() {
		try{
			for(int i=0; i<50000; i++){
				if(Thread.interrupted()){
					throw new InterruptedException(); //如果中断标志为true,抛出异常
				}
				System.out.println("i=" + (i+1));
			}

		} catch (InterruptedException e) {
			System.out.println("线程已被中断!");
			System.out.println("the signal of interrupted: "+Thread.interrupted()); //interrupted()方法的清除中断标志位功能检测
			e.printStackTrace();
			
		}
		
	}

}
<pre name="code" class="java">public class Run {
	public static void main(String args[]){
		
		try{
			MyThread thread = new MyThread();
			thread.start(); //启动线程
			Thread.sleep(100);
			thread.interrupt(); //产生中断信号	
		} catch (InterruptedException e) {
			System.out.println("main catch");
			e.printStackTrace();
			
		}
	}

}


 上述代码的执行结果为: 

可以看到正在执行自增操作的线程被中断,还可以观察到interrupted()方法会清除中断标志为false。

处于sleep()状态的线程中断:

public class MyThread extends Thread{
	
	@Override
	public void run() {
		try{
			System.out.println("run begin");
			Thread.sleep(20000);
			System.out.println("run end");
			
		} catch (InterruptedException e) {
			System.out.println("线程已被中断!");
			System.out.println("the signal of interrupted: "+Thread.interrupted());
			e.printStackTrace();
			
		}
		
	}

}
public class Run {
	public static void main(String args[]){
		
		try{
			MyThread thread = new MyThread();
			thread.start();
			Thread.sleep(100);
			thread.interrupt();	
		} catch (InterruptedException e) {
			System.out.println("main catch");
			e.printStackTrace();
			
		}
	}

}
上述代码的执行结果如下图所示:


可以看到在阻塞状态(sleep,wait,join)的线程的中断实现,并不需要手动抛出异常,线程会自动抛出异常。并且在抛出异常的同时,还会将中断标志位置为false。但并不是所有的阻塞状态都可以自动抛出InterruptedException,像某些I/O操作或者内部锁操作,但是这些阻塞状态又会抛出自己特殊的异常,用这些异常同样可以实现中断。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值