线程的中断与InterruptedException

一直不明白为什么Thread.sleep(long millis)方法为啥会抛出checked异常InterruptedException,在网上找到了一篇非常好的文章《Java 理论与实践: 处理 InterruptedException》,以下主要是通过代码来逐一说明这篇几个关键的要点。

线程中断的标志

其实 Thread类中维护这一个状态变量还表示线程是否已中断,我们可以通过 isInterrupted()方法返回该线程的中断状态。另外Thread还提供了一个静态方法 interrupted()同样能返回该线程的中断状态,不过调用该方法将导致Thread的中断状态被清除(即重置为默认值false)。

阻塞方法

在上述文章 《Java 理论与实践: 处理 InterruptedException》说明了阻塞方法的概念,并说明了阻塞方法抛出 InterruptedException其实是一种线程的可取消机制。

非阻塞方法的中断处理

若线程运行的任务是非阻塞的,则调用线程的interrupt()方法并不会的导致线程中断,该方法作用其实是改变线程的中断标志。
	public static void test1() throws InterruptedException {
		//未对中断状态进行处理,该线程并不会中断
		Thread thread = new Thread() {
			private int i = 0;
			public void run() {
				while (true) {
					i++;
					System.out.println(i);
				}
			};
		};
		thread.start();

		Thread.sleep(1000);
		System.out.println(thread.isInterrupted()); // 输出false
		thread.interrupt();//中断线程
		System.out.println(thread.isInterrupted()); // 输出true
	}
要让该线程支持中断机制应只需做如下修改
		Thread thread = new Thread() {
			private int i = 0;
			public void run() {
				//检查线程的中断状态
				while (!isInterrupted()) {
					i++;
					System.out.println(i);
				}
			};
		};

阻塞方法的中断处理:处理InterruptedException

如果抛出 InterruptedException意味着一个方法是阻塞方法,那么调用一个阻塞方法则意味着您的方法也是一个阻塞方法,而且您应该有某种策略来处理 InterruptedException
通过查看官方的API文档,我们可以知道 Thread方法 sleep(long millis) throws InterruptedException有如下说明:
(1)当线程调用sleep()方法进入阻塞状态后,如果任何线程中断了该线程,将抛出 InterruptedException异常。
(2)抛出 InterruptedException异常后,当前线程的中断状态将被清除(即重置为默认值false)
	public static void test1() throws InterruptedException {
		Thread thread_A = new Thread() {
			private int i = 0;
			public void run() {
				//该循环不会终止
				while (!isInterrupted()) {  
		            i++;  
		            System.out.println(i);  
		            
		            try {
						sleep(5000);
					} catch (InterruptedException e) {
						e.printStackTrace();
						System.out.println(isInterrupted()); //中断状态被清除,输出false
					}
		        }  
			};
		};
		thread_A.start();

		Thread.sleep(1000);
		//中断线程A,这时候线程A正处于阻塞状态,将抛出InterruptedException
		thread_A.interrupt();
	}
不得不说我们大多数做法就是生吞 InterruptedException,良好的编程习惯应当要视情况对该异常做一些处理,如对上述代码做如下修改
		Thread thread_A = new Thread() {
			private int i = 0;
			public void run() {
				while (!isInterrupted()) {  
		            i++;  
		            System.out.println(i);  
		            
		            try {
						sleep(5000);
					} catch (InterruptedException e) {
						interrupt(); //恢复设置成中断状态
					}
		        }  
			};
		};

上述仅仅对 Threadsleep()方法作出说明,还有很多方法同样会抛出 InterruptedException。正确的做法是先认真看其API说明文档,避免生吞了该异常。








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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值