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

来源:互联网 发布:文字转音频软件 编辑:程序博客网 时间:2024/05/20 11:31

中断: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语言来说就有意义,在其他线程中调用阻塞状态的线程的中断,抛出一个异常,表示是被其他线程打断的,被当断的线程不再处于休眠状态,会被强制的唤醒,这时能做一些收尾操作,不会继续睡眠下去,不会再执行。

举个栗子:

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线程falsejava.lang.InterruptedException: sleep interruptedThread-0:我不想死!main:结束!




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

阅读全文
0 0
原创粉丝点击