当前位置: 首页 > 图灵资讯 > 技术篇> 关于interrupt(),interrupted(),isInterrupted()用法分析

关于interrupt(),interrupted(),isInterrupted()用法分析

来源:图灵教育
时间:2023-06-07 09:45:52

我认为代码很容易解释这个问题。下面将进行总结。

点击此处或向下阅读总结:

直接来一个小代码吧:

public class Interrupt {    public static void main(String[] args) {        Thread t = new Thread(new Worker());        t.start();        try {            Thread.sleep(5);        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        t.interrupt();        System.out.println("Main thread stopped.");    }    public static class Worker implements Runnable {        public void run() {            System.out.println("Worker started.");            boolean f; // 用于检测interupted()的第一次返回值            int i = 0;            Thread c = Thread.currentThread();            System.out.println(isinterupted()while之前的线程中断状态:" + c.isInterrupted());            while (!(f = Thread.interrupted())) {// 判断是否中断,如果中断,跳出并清除中断标志位置                // 一旦检测到中断,interrupted()第一次回到true,就可以跳出循环,第二次和以后都会回到falsee                System.out.println(while内,还没有中断,interrupted()返回值为:"" + f);                System.out.println(c.getName() + "  " + i++ + "  " + c.isInterrupted());            }            System.out.println(”跳出循环是Interupted()返回值的第一次中断 + f);            System.out.println(isinterupted():" + c.isInterrupted()); // 为false,因为interrupt()会清除中断标志位,显示为未中断            System.out.println(interupted()第二次及以后的返回值:" + Thread.interrupted());            c.interrupt();            System.out.println()再次中断后,查询isinterupted():" + c.isInterrupted());            System.out.println("Worker stopped.");        }    }}

运行结果:

关于interrupt(),interrupted(),isInterrupted()用法分析_System

...省略一些相同的步骤

关于interrupt(),interrupted(),isInterrupted()用法分析_跳出循环_02

分析说明:

interrupt()用于中断线程,调用该方法的线程状态将被放置为“中断”状态。注意:线程中断只是设置线程的中断状态,不会停止线程。用户需要监控线程的状态并进行处理。在这里,我们可以看到线程在中断后继续下降,并且没有强制终止线程。

为什么主线程执行t?.interrupt()然后调用isinterupt()返回false?

因为在这里调用interupted()将清除中断标志位。

另一种情况:如果线程在wait, sleep,join受阻时,调用interupt()方法,不仅会清除中断标志位,还会抛出interuptedException异常。这个例子最后会在下面给出。

让我们来看看interupted()和isinterupted()

public static boolean interrupted() {           return currentThread().isInterrupted(true);   }public boolean isInterrupted() {         return isInterrupted(false);   }  private native boolean isInterrupted(boolean ClearInterrupted);

这是一种看不到源代码的native方法,但注意表明,如果输入false,中断标志位不会被删除,如果输入true,中断标志位将被删除。

isInterrupted ()非常诚实,只查询中断标志位,不改变中断标志位。

如果线程在wait, sleep,join受阻时,调用interupt()方法,不仅会清除中断标志位,还会抛出InteruptedException异常。

然后给出另一个例子。

public class Interrupt {    public static void main(String[] args) throws Exception {        Thread t = new Thread(new Worker());        t.start();        Thread.sleep(100);        t.interrupt();        System.out.println("Main thread stopped.");    }    public static class Worker implements Runnable {        public void run() {            System.out.println("Worker started.");            try {                Thread.sleep(500); // 此时,Interupt()将抛出Interuptedexception            } catch (InterruptedException e) {                Thread thread = Thread.currentThread();                System.out.println(isinterupted()在再次中断之前:" + thread.isInterrupted());                System.out.println(interupted()在再次中断之前:" + Thread.interrupted());                // 再次调用interrupt方法中断自己,将中断状态设置为“中断”                thread.interrupt();                System.out.println(isinterupt()后isinterupted():" + thread.isInterrupted());                System.out.println(”interupt()再次interupt()后第一次interupted()返回:" + Thread.interrupted());// clear status                // interrupted()判断是否中断,中断标志位也将被清除                System.out.println("interrupted()此时,判断ISInterupted: " + thread.isInterrupted());                System.out.println("---------After Interrupt Status Cleared----------");                System.out.println((interupt()再次interupt()后第二次interupted()返回: " + Thread.interrupted());                System.out.println(此时,判断ISInterupted: " + thread.isInterrupted());            }            System.out.println("Worker stopped.");        }    }}

运行结果:

关于interrupt(),interrupted(),isInterrupted()用法分析_线程中断_03

总结:

interrupt()方法

如果sleep不中断,wait,如果join方法或文档中描述的其他情况,则不会抛出interuptexception异常,也不会清除中断标志位,isInterrupt()返回true。

若中断sleep,wait,join等,会抛出interruptexception异常,会清除中断标志位,isInterrupt()返回false。

interrupted()方法

第一次使用返回true并清除中断标志位后,查询中断状态isinterupt()将返回false。刚才第一个例子也看到了,用了 第一次返回的true可以跳出循环。第二次和以后都是返回false。

isInterrupted()方法

查询中断标志位,判断是否中断并返回true或false。

若中断sleep,wait,join等。,会抛出interuptexception异常,中断标志位将被清除。那么这种情况应该怎么处理呢?为了保证数据的一致性和完整性,我们需要使用thread.interrupt()方法再次中断自己,设置中断标志位。例子如下:

public class test {    public static void main(String[] args) throws InterruptedException {        Thread t1 = new Thread() {            public void run() {                while (true) {                    if (Thread.currentThread().isInterrupted()) {                        System.out.println("Interruted!");                        break;                    }                    try {                        Thread.sleep(2000); // 睡眠中断会清除中断标志                    } catch (InterruptedException e) {                        // 如果没有下面这句话,虽然这个线程在外面中断,但只要睡眠过程中断                        // 中断标志位将被清除,仍处于无限循环,CPU资源将竞争                        Thread.currentThread().interrupt(); // 再次中断上中断标记                    }                    Thread.yield();                }            }        };        t1.start();        Thread.sleep(200);        t1.interrupt();    }}

Thread.sleep()该方法因中断而抛出异常。此时,它将清除中断标记。如果不处理,则在下一个循环开始时无法捕获中断。因此,在异常处理中,中断标记位置将再次设置。

下面给出官方文件说明:

interrupt
public void interrupt()

中断线程。

如果当前线程没有中断自己(这在任何情况下都是允许的),则调用该线程的checkaccess方法,可能会抛出securityexception。

如果线程正在调用Objectwait()、wait(long)或wait(long, int)方法,或者这种join()、join(long)、join(long, int)、sleep(long)或sleep(long, int)如果在方法过程中受阻,中断状态将被清除,它还将收到InteruptedException。

如果线程在可中断通道上 I/O 如果操作中受阻,通道将关闭,线程的中断状态将设置,线程将收到ClosedByinteruptexception。

如果该线程在Selector中受阻,则将设置该线程的中断状态。它将立即从选择操作返回,并可能具有非零值,就像调用选择器的wakeup方法一样。

若以前的条件未保存,则将设置线程的中断状态。

不处于活动状态的线程中断不需要任何效果。

抛出:

SecurityException- 如果当前线程不能修改该线程

interrupted

public static boolean interrupted()

测试当前线程是否中断。线程中断状态这种方法被清除了。换句话说,如果该方法连续调用两次,第二次调用将返回 false(第一次调用清除中断状态后,第二次调用检查中断状态前,当前线程再次中断的除外)。

由于中断时不处于活动状态的线程会返回,因此忽略了线程中断。 false 方法反映出来。

返回:

如果当前线程中断,则返回true;否则返回false

另请参见:

isInterrupted()

isInterrupted

public boolean isInterrupted()

测试线程是否中断。线程中断状态不受该方法的影响。

由于中断时不处于活动状态的线程会返回,因此忽略了线程中断。 false 方法反映出来。

返回:

如果该线程中断,则返回true;否则返回false

另请参见:

interrupted()