线程中断,interrupt(),interrupted,isInterrupted()

中断:cpu有更加紧急的程序需要处理的时候,cpu会暂时终止当前线程的执行转而去执行处理紧急程序的过程。

在Java中的中断指的是当前线程停止执行。java中的中断是调用Thread.interrupt()的方法来实现的。这个方法并不是调用了就一定能中断线程的。调用该方法,只是修改了被调用线程的中断状态。告知当前线程,它被中断了。


说到interrupt()方法我就不得不说之前我一直对interrupt()、interrupted()、isInterrupted()这三个方法分不清。在这里我简单总结一下,避免哪天脑子又抽了ʅ(´◔౪◔)ʃ

1.interrupt():想要中断某个线程就调用这个方法,它会修改线程的中断状态,当运行线程监测到自己的中断状态改变时就会中断自己,如果是非阻塞状态下的线程调用interrupt()方法只会修改状态并不会起作用,通过调用Thread.isInterrupted()可以查看,线程的中断状态为true。对于阻塞中的线程。比如调用了sleep(),wait(),join()等方法的线程。这些线程受到中断信号后,会抛出InterruptedException,并将中断状态修改为false.也就是重置中断状态为false.

2.isInterrupted():在上面介绍interrupt的时候提到 isInterrupted() 是查看线程中断状态的。isInterrupted()只会返回的是调用该方法的线程的中断状态,不会改变线程的中断状态。

3.interrupted():这个方法要和isInterrupted()区分开,isInterrupted()是作用在调用该方法的线程上的,interrupted()是作用在当前运行的线程上的,它会返回当前线程的中断状态,并重置中断状态,也就是说它是可以改变线程中断状态的。

    public static boolean interrupted()
    {
        return currentThread().isInterrupted(true);
    }
对以上三种状态的区别有兴趣的推荐去看一篇写的不错的博客: interrupt、interrupted 、isInterrupted 区别

中断:ok,扯远了,继续说中断,通过了上面的简单介绍我们可以发现,中断方法interrupt()真正起作用的是在阻塞状态的线程,也就是调用wait,sleep,join的线程。

其实从操作上来看处于阻塞状态的线程本来就没有获得cpu,实际上中断也并没有什么作用,但是对于Java语言来说就有意义,在其他线程中调用阻塞状态的线程的中断,抛出一个异常,表示是被其他线程打断的,被当断的线程不再处于休眠状态,会被强制的唤醒,这时能做一些收尾操作,不会继续睡眠下去,不会再执行。

扫描二维码关注公众号,回复: 3817584 查看本文章

举个栗子:

public class SimpleThread {

	public static String importantInfo[] = {"母马吃燕麦","狗吃骨头","小马吃奶","小孩吃奶"};
	
	//显示信息,一部分输出当前线程的名字,一部分输出传入的信息
	static void printMessage(String message){
		String threadName = Thread.currentThread().getName();
		System.out.format("%s:%s%n",threadName,message);
	}
	
    private static class MessageLoop implements Runnable {

		public void run() {
			try {
			for (int i = 0; i < importantInfo.length; i++) {
			
					Thread.sleep(4000);
					printMessage(importantInfo[i]);
				
			}
			} catch (InterruptedException e) {
				e.printStackTrace();
				printMessage("我不想死!");
			}
		}

    }
    
    public static void main(String[] args) throws InterruptedException {
		long patience = 1000*10;
		printMessage("创建MessageLoop线程");
		Long startTime = System.currentTimeMillis();
		Thread t = new Thread(new MessageLoop());
		t.start();
		t.join(1000);
		while (t.isAlive()){
			printMessage("等待MessageLoop线程结束");
			t.join(1000);//join有参数,会阻塞1000秒,此后不管子线程是否结束都会执行主线程,多次调用结果和一次调用是一样的,只不过增加阻塞。
			if((System.currentTimeMillis()-startTime)>patience&&t.isAlive()){
				printMessage("等待时间过长,中断MeassageLoop线程");
				t.interrupt();
				t.join();
			}
		}
		printMessage("结束!");
	}
}
运行结果:

main:创建MessageLoop线程
main:等待MessageLoop线程结束
main:等待MessageLoop线程结束
main:等待MessageLoop线程结束
main:等待MessageLoop线程结束
Thread-0:母马吃燕麦
main:等待MessageLoop线程结束
main:等待MessageLoop线程结束
main:等待MessageLoop线程结束
Thread-0:狗吃骨头
main:等待MessageLoop线程结束
main:等待MessageLoop线程结束
main:等待时间过长,中断MeassageLoop线程
false
java.lang.InterruptedException: sleep interruptedThread-0:我不想死!
main:结束!




本文有参考《java并发编程系统与模型》的相关知识点。

猜你喜欢

转载自blog.csdn.net/sinat_36265222/article/details/78327124