关于java:如何正确的中断线程你的姿势是否正确

32次阅读

共计 2592 个字符,预计需要花费 7 分钟才能阅读完成。

Java 进行线程的逻辑(协同、告诉)

在 Java 程序中,咱们想要进行一个线程能够通过 interrupt 办法进行进行。然而当咱们调用 interrupt 办法之后,它可能并不会立即就会进行线程,而是告诉线程须要进行。线程接管到告诉之后会依据本身的状况判断是否须要进行,它可能会立刻进行,也有可能会执行一段时间后进行,也可能基本就不进行。

那么 Java 为什么要抉择这种非强制性的线程中断呢?其实更多是为了数据安全,保障程序的健壮性。因为咱们不晓得程序正在做什么事件。如果贸然进行,可能会造成数据的错乱、不残缺。

一个简略的例子

public class _24_ThreadTest implements Runnable {

    @Override
    public void run() {
        int count = 0;
        while (!Thread.currentThread().isInterrupted() && count <= 2000) {System.out.println("count:" + count++);
        }
    }

    public static void main(String[] args) throws Exception {_24_ThreadTest threadTest = new _24_ThreadTest();
        Thread thread = new Thread(threadTest);
        thread.start();
        Thread.sleep(10);
        // 中断线程
        thread.interrupt();}
}

这个例子是一个简略的通过 interrupt 中断线程的案例,run 办法中通过判断以后线程是否中断,并且 count 是否大于 2000 来进行循环。如果线程中断则退出循环,线程执行完结。这种就属于线程失常进行的状况。

Sleep 是否会收到线程中断信号

public class _24_ThreadTest implements Runnable {

    @Override
    public void run() {
        int count = 0;
        while (!Thread.currentThread().isInterrupted() && count <= 2000) {
            try {System.out.println("count:" + count++);
                // 子线程睡眠
                Thread.sleep(1000 * 2);
                System.out.println("办法体:" + Thread.currentThread().isInterrupted());
            } catch (InterruptedException e) {System.out.println("异样:" + Thread.currentThread().isInterrupted());
                // 线程中断标记位被重置为 false
                e.printStackTrace();}
        }
    }

    public static void main(String[] args) throws Exception {_24_ThreadTest threadTest = new _24_ThreadTest();
        Thread thread = new Thread(threadTest);
        thread.start();
        Thread.sleep(10);
        // 中断线程
        thread.interrupt();}
}

如果在子线程中睡眠中,主线程通过 interrupt 办法进行中断,那么子线程还能不能收到中断信号。其实在这种状况下线程也是能够接管到信号告诉的,这个时候会抛出 InterruptedException,并且将线程中断标记位设置为 false。

在抛出异样后,线程标记位被设置为 false,那么在下次循环判断 count 没有为 false 的状况下,还是能够进入循环体的。这个时候线程就无奈进行。

执行后果:

案例场景

在进行一些后台任务通过线程跑的时候,如果在循环中遇到线程中断异样,咱们须要终止当前任务,并且通知客户端当前任务执行失败的是哪条记录,这种状况下就能够通过异样中再次中断的形式来进行线程,并且能够返回给客户端以后出现异常的记录是哪条。而不会是接着执行上来。

解决办法

public class _24_ThreadTest implements Runnable {

    @Override
    public void run() {
        int count = 0;
        while (!Thread.currentThread().isInterrupted() && count <= 2000) {
            try {System.out.println("count:" + count++);
                // 子线程睡眠
                Thread.sleep(1000 * 2);
                Thread.currentThread().interrupt();
                System.out.println("办法体:" + Thread.currentThread().isInterrupted());
            } catch (InterruptedException e) {
                // 再次中断
                Thread.currentThread().interrupt();
                System.out.println("异样:" + Thread.currentThread().isInterrupted());
                e.printStackTrace();}
        }
    }

    public static void main(String[] args) throws Exception {_24_ThreadTest threadTest = new _24_ThreadTest();
        Thread thread = new Thread(threadTest);
        thread.start();
        Thread.sleep(10);
        // 中断线程
        thread.interrupt();}
}

既然咱们曾经晓得,在呈现线程中断异样之后线程中断标记位会被重置为 false,那么咱们能够在异样中手动的再次中断以后线程,那么就能够齐全进行线程工作。

总结

下面咱们简略介绍了如何正确的进行线程,如果在当前的面试中被问到这类问题,那么你是不是能够晦涩的答复面试官了。

在 run 办法中遇到异样,咱们是不能间接生吞的,肯定要做解决,你能够是简略的日志记录,也能够中断线程。但就是不能不做任何解决。

其实还有其余的一些办法来进行线程,比方 stop(),这类办法已被舍弃,这种强制进行可能会引起线程的数据安全问题,所以曾经不再举荐应用了。

正文完
 0