java线程学习(三):线程中断 interrupt() 方法的使用

上一章节中,我们对线程终止stop方法进行了讲解,stop终止线程的方法已经被丢弃,原因是线程的终止太暴力,会导致不必要的数据错误,所以stop方法在不自信的情况下,慎用慎用。。。。同时,也提供了较为完善的终止方案了。
本节就来学习线程中断 interrupt() 方法的使用:
一、先来看看源码

	public void interrupt() {
		if (this != currentThread()) {
			this.checkAccess();
		}

		Object var1 = this.blockerLock;
		synchronized (this.blockerLock) {
			Interruptible var2 = this.blocker;
			if (var2 != null) {
				this.interrupt0();
				var2.interrupt(this);
				return;
			}
		}

		this.interrupt0();
	}

	public static boolean interrupted() {
		return currentThread().isInterrupted(true);
	}

	public boolean isInterrupted() {
		return this.isInterrupted(false);
	}

可以看出目前跟中断相关的有三个方法,分别是:

  • interrupt(): 实例方法。它通知目标线程中断,也就是设置中断标志位(中断标志位表示当前线程已经被中断了)。
  • isInterrupted():实例方法。用来判断当前线程是否有被中断(通过检查中断标志位)
  • interrupted():静态方法。用来判断当前线程的中断状态,并清除当前线程的中断标志为状态。

二、我们来看看这些例子加理解:

栗子一:只使用interrupt()方法:

public class Interrupt_demo {
	
	/**
	 * 例子1:
	 * 只使用interrupt方法
	 * @author fei
	 *
	 */
	public static class Interrupt_demo1 extends Thread{

		@Override
		public void run() {
			System.out.println("线程"+Thread.currentThread().getName()+"在运行~~~~");
			Thread.yield();
		}
	}
	
	public static void main(String[] args) {	
		//创建10条线程
		for (int i = 0; i < 10; i++) {
			Thread thread=new Interrupt_demo1();
			thread.start();
			//如果是偶数,那么就中断
			if (i%2==0) {
				thread.interrupt();
			}
		}
	}
}

创建10条线程,当偶数次的时候,中断该线程的执行,打印出该信息:

明显看到,就算中断了,也一样会执行10条线程。说明单单使用这个interrupt()方法是没有什么效果的。

栗子二:使用interrupt()配合isInterrupted()方法:

package stop_demo;

public class Interrupt_demo {
	
	
	/**
	 * 例子1:
	 * 只使用interrupt方法
	 * @author fei
	 *
	 */
	public static class Interrupt_demo1 extends Thread{

		@Override
		public void run() {
		      //相对栗一添加对线程是否中断进行判断
			if (Thread.currentThread().isInterrupted()) {
				System.out.println("线程"+Thread.currentThread().getName()+"已被中断!!");
				return;
			}
			System.out.println("线程"+Thread.currentThread().getName()+"在运行~~~~");
			Thread.yield();
		}
	}
	
	public static void main(String[] args) {
		
		//创建10条线程
		for (int i = 0; i < 10; i++) {
			Thread thread=new Interrupt_demo1();
			thread.start();
			//如果是偶数,那么就中断
			if (i%2==0) {
				thread.interrupt();
			}
		}
		
	}
}

运行后输出:
在这里插入图片描述
可以看到,使用interrupt()配合isInterrupted()方法是可以达到中断线程的目的的,这就理解interrupt()方法设置标志位的含义了。同时也可以看出,isInterrupted()方法实际上和上一篇文章stopThread()方法类似,但是isInterrupted()更为好用,因为isInterrupted()可以用在循环体中,有wait和sleep操作的线程中。

栗子三:三个方法配合使用

package stop_demo;

public class Interrupt_demo {
	
	
	/**
	 * 例子1:
	 * 只使用interrupt方法
	 * @author fei
	 *
	 */
	public static class Interrupt_demo1 extends Thread{

		@Override
		public void run() {
			if (Thread.interrupted()) {
				System.out.println("线程"+Thread.currentThread().getName()+"判断为中断,但已经清除中断");
				//看是否进入该判断,如果不进入那么证明中断已经清除了
				if (Thread.currentThread().isInterrupted()) {
					System.out.println("线程"+Thread.currentThread().getName()+"已被中断!!");
					return;
				}	
			}
			
			System.out.println("线程"+Thread.currentThread().getName()+"在运行~~~~");
			Thread.yield();
		}
	}
	
	public static void main(String[] args) {
		
		//创建10条线程
		for (int i = 0; i < 10; i++) {
			Thread thread=new Interrupt_demo1();
			thread.start();
			//如果是偶数,那么就中断
			if (i%2==0) {
				thread.interrupt();
			}
		}
		
	}
	
}

运行后输出:
在这里插入图片描述
可以看到,使用静态方法判断中断线程,清除后,该线程就不是中断状态了,所以

if (Thread.currentThread().isInterrupted()) {
					System.out.println("线程"+Thread.currentThread().getName()+"已被中断!!");
					return;
				}	

该方法就不会执行了。

猜你喜欢

转载自blog.csdn.net/shenhaiyushitiaoyu/article/details/85007957
今日推荐