Java 线程中断相关方法:interrupt() isInterrupted() interrupted()

interrupt() 方法只是改变中断状态而已,它不会中断一个正在运行的线程。如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,此时调用该线程的interrupt()方法,那么该线程将抛出一个 InterruptedException中断异常。

使用stop方法虽然可以强行终止正在运行或挂起的线程,但使用stop方法是很危险的,可能会产生不可预料的结果,因此,并不推荐使用stop方法来终止线程。Thread.interrupt()方法: 作用是中断线程。将会设置该线程的中断状态位,即设置为true,中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序本身。线程会不时地检测这个中断标示位,以判断线程是否应该被中断(中断标示值是否为true)。它并不像stop方法那样会中断一个正在运行的线程 interrupt()方法只是改变中断状态,不会中断一个正在运行的线程。Java虚拟机对会抛出InterruptedException异常的方法进行了特别处理:Java虚拟机会将该线程的中断标志位清除,然后抛出InterruptedException,这个时候调用isInterrupted方法返回的也是false。

一旦线程的中断状态被置为“中断状态”,就会抛出中断异常。

(1)interrupt:置线程的中断状态。

(2)isInterrupted:测试线程(*调用该方法的线程*)是否已经中断,不清除中断状态。

(3)interrupted:测试当前线程(当前线程是指运行interrupted()方法的线程)是否已经中断,且清除中断状态。

看源码可以得知:interrupted方法底层就是调用了清除标志位的isInterrupted方法。

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

private native boolean isInterrupted(boolean ClearInterrupted);

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

演示demo:

public class Test {

    public static void main(String[] args) {
/*        testWait();
        占有锁
        interrupt标志位: false
        interrupt标志位: true
        线程中断*/
        
/*        testSleep();
        interrupt标志位: false
        interrupt标志位: true
        线程testSleepTread中断*/
        
/*      testJoin();
        Task is interrupted*/
    }

    public static void testSleep() {
        Runnable testSleepTread = () -> {
            try {
                Thread.sleep(1000 * 50);
            } catch (InterruptedException e) {
                System.out.println("线程testSleepTread中断");
            }
        };
        Thread thread1 = new Thread(testSleepTread);
        thread1.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("interrupt标志位: " + thread1.isInterrupted());
        thread1.interrupt();
        System.out.println("interrupt标志位: " + thread1.isInterrupted());
    }

    public static void testWait() {
        Object lock = new Object();
        Runnable testWaitTread = () -> {
            synchronized (lock) {
                System.out.println("占有锁");
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    System.out.println("线程中断");
                }
            }
        };
        Thread threadHasLock = new Thread(testWaitTread);
        threadHasLock.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("interrupt标志位: " + threadHasLock.isInterrupted());
        threadHasLock.interrupt();
        System.out.println("interrupt标志位: " + threadHasLock.isInterrupted());
    }

    public static void testJoin() {
        Thread thread1 = new Thread(new Task());
        thread1.start();
        try {
            thread1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    static class Task implements Runnable {
        @Override
        public void run() {
            try {
                Thread.currentThread().interrupt();
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                System.out.println("Task is interrupted");
            }
        }
    }

}
posted @ 2022-04-12 14:46  aixueforever  阅读(174)  评论(0编辑  收藏  举报