Java多线程学习笔记(一)之中断中的Interrupt,interrupted(),isInterrupted()

 

 


  • 1、关于中断

在Java中中断最初是通过stop()来终止线程的,后来发现这样简单粗暴的停止线程会产生很多问题(例如对象monitor的释放),所以改为deprecated,推荐使用interrupt()来中断线程。而对于线程来说,会持有一个interrupted标记变量,调用interrupt()方法并不会使线程立即中断,而是把标记变量设置为true,而对于线程的中断则需要自己去作处理。下面这段代码可以说明:

class ThreadTest1{
	public static void main(String[] args) throws InterruptedException {
		Thread thread = new Thread() {
			@Override
			public void run() {
				for (int i = 0; true; i++) {
					System.out.println("Thread is running " + i);
				}
			}
		};
		thread.start();
		Thread.sleep(1);
		thread.interrupt();
		/**
		 * 输出:
		 *  Thread is running 0
			Thread is running 1
			Thread is running 2
			Thread is running 3
			Thread is running 4
			Thread is running 5
			Thread is running 6
			Thread is running 7
			Thread is running 8
			Thread is running 9
			Thread is running 10
			Thread is running 11
			Thread is running 12
			Thread is running 13
			Thread is running 14
			Thread is running 15
			Thread is running 16
			Thread is running 17
			...
		 */
	
}

线程会一直无限执行。

  • 2、利用中断标记来手动中断线程

那么对于上面的代码我们如何做到中断线程呢?上面说到,调用interrupt()方法后,会把线程的中断标记设置为true,我们可以利用这个标记来进行手动的判断中断线程。以下是修改后的代码:


		Thread thread = new Thread() {
			@Override
			public void run() {
				for (int i = 0; true; i++) {
					if (this.isInterrupted()) {
						System.out.println("This thread is interrupted.");
						break;
					}
					System.out.println("Thread is running " + i);
				}
			}
		};
		thread.start();
		Thread.sleep(1);
		thread.interrupt();
		/**
		 * 输出:
		 *  Thread is running 0
			Thread is running 1
			Thread is running 2
			Thread is running 3
			Thread is running 4
			Thread is running 5
			Thread is running 6
			Thread is running 7
			Thread is running 8
			Thread is running 9
			Thread is running 10
			Thread is running 11
			Thread is running 12
			Thread is running 13
			Thread is running 14
			Thread is running 15
			Thread is running 16
			Thread is running 17
			This thread is interrupted.
		 */
	

 

我们在循环里加入了一个中断标识的判断,一旦中断标识为true,立刻停止循环,从而中断线程。同样的,除了isInterrupted(),用Thread.interrupted()效果也是一样的。

  • 3、关于获取中断标记,interrupted()和isInterrupted()的区别

获取中断标记有两个方法,一个是Thread.interrupted(),另外一个是this.isInterrupted()。前者是静态方法,后者是实例方法,下面是二者的源码:

可以看到二者都是调用了isInterrupted(boolean)这个本地方法,而这个本地方法会根据参数来选择是否重置interrupted state。就是说isInterrupted()不会重置中断状态,而interrupted()会重置状态。下面我们通过代码测试一下:

	public static void main(String[] args) throws InterruptedException {

		Thread thread = new Thread() {
			
			@Override
			public void run() {
				while (true) {
					if (Thread.interrupted()) {
						break;
					}
					
					System.out.println("线程未被中断,当前线程状态:" + this.isInterrupted());
					
				}
				System.out.println("************线程已被中断,当前线程状态:" + this.isInterrupted());
			}
		};
		
		thread.start();
		Thread.sleep(1);
		thread.interrupt();
		/*
		 *  线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
		 	************线程已被中断,当前线程状态:false
		 */
	
	}

 我们先看isInterrupted()的效果,在线程执行的最后,线程已经中断,线程的中断标记状态为false,而因为打印该行,说明已经跳出了while循环,说明if语句为真,也就是Thread.interrupted()返回true,但最后已经被重置了。那么下面我们继续看看isInterrupted()的效果,代码如下:

public static void main(String[] args) throws InterruptedException {
		Thread thread = new Thread() {
			
			@Override
			public void run() {
				while (true) {
					if (isInterrupted()) {
						break;
					}
					
					System.out.println("线程未被中断,当前线程状态:" + this.isInterrupted());
					
				}
				System.out.println("************线程已被中断,当前线程状态:" + this.isInterrupted());
			}
		};
		
		thread.start();
		Thread.sleep(1);
		thread.interrupt();
		/*
		 *  线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			线程未被中断,当前线程状态:false
			************线程已被中断,当前线程状态:true
		 */
	}

可以看到,我们只是把if语句里的条件改了一下,其他位置并没有改变,但是最后线程的状态为true,说明interrupt()方法正如所说的那样,把线程中断标识改为了true。


  • 说在最后

如果文章有疏漏,请及时指出,大家相互交流学习,谢谢。


  • 参考文章

更加深入全面的大牛的传送门

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值