线程中断

中断代表线程状态,每个线程都关联了一个中断状态,是一个 true 或 false 的 boolean 值,初始值为 false。

Thread类中的有个三个关于中断的方法

public void interrupt(){}

中断目标线程,线程中断状态true。 ```java public void interrupt() {
if (this != Thread.currentThread())
checkAccess();

synchronized (blockerLock) {                                      
    Interruptible b = blocker;                                    
    if (b != null) {                                              
        interrupt0();           // Just to set the interrupt flag 
        b.interrupt(this);                                        
        return;                                                   
    }                                                             
}                                                                 
interrupt0();                                                     

}


- 当线程被Object中定义的 wait()、wait(long)或wait(long, int)以及Thread中的jion()、join(long)、join(long, int)、sleep(long)或sleep(long, int)进入阻塞状态,调用interrupt()时线程的中断标记会被清除(设置为false),同时抛出一个InterruptedException异常。
- 当线程处于非阻塞的运行状态时,调用interrupt()方法不会响应。一般通过Thread.isInterrupted()判断状态。



##### public static boolean interrupted() {} 


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

用于判断当前线程的中断状态,调用时会清除当前线程的中断状态(置为flase),连续调用两次返回false。

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

判断目标线程是否被中断,不会清除中断标记。


中断状态被清除的特殊情况

1.当一个线程处于被阻塞状态,使用public void interrupt(){}方式中断该线程,将会抛出一个InterruptedException的异常,同时中断状态将会被清除(从true变成false)
 public static void main(String[] args) {
        Thread t1 = new Thread() {
            @Override
            public void run() {
                // while在try中,通过异常中断就可以退出run循环
                try {
                    while (true) {
                        // 当前线程处于阻塞状态,异常必须捕捉处理,无法往外抛出
                        Thread.sleep(2000);
                    }
                } catch (InterruptedException e) {
                    System.out.println("Interruted When Sleep");
                    boolean interrupt = this.isInterrupted();
                    // 中断状态被复位
                    System.out.println("interrupt:" + interrupt);
                }
            }
        };
        t1.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 中断处于阻塞状态的线程
        t1.interrupt();
    }

输出

Interruted When Sleep
interrupt:false

要注意while中判断的写法,容易引起死循环。

while(!this.isInterrupted())

中断与synchronized

线程的中断操作对于正在等待获取的锁对象的synchronized方法或者代码块并不起作用

public class ThreadInterruptTest {

    public static void main(String[] args) {
        try {
            Object object = new Object();

            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        synchronized (object) {
                            Thread.sleep(5000);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();

            Thread.sleep(2000);

            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (object){
                        System.out.println("get lock");
                    }
                }
            });

            thread.start();

            Thread.sleep(1000);

            thread.interrupt();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

5秒之后打印:

get lock

如何退出线程?

1.使用voliate变量

public class Interrupt {


    private volatile static boolean flag = false;

    public static void main(String[] args) throws InterruptedException {


        Thread thread = new Thread(() -> {
            while (!flag) {
                System.out.println("thread Running");
            }
            System.out.println("thread break");

        });
        thread.start();
        Thread.sleep(2000);
        flag = true;
    }


}
Copyright © tracyliu-FE 2021 all right reserved,powered by Gitbook文件修订时间: 2022-03-06 12:52:33

results matching ""

    No results matching ""