java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java 线程中断

Java中线程中断的几种方法小结

作者:爪哇码农

在Java中,线程中断是一种协作机制,它通过设置线程的中断标志位来通知线程需要中断,本文主要介绍了Java中线程中断的几种方法小结,具有一定的参考价值,感兴趣的可以了解一下

使用线程的stop()来中断线程

这种方式是直接调用线程的stop()方法,可以直接让线程终止运行,是一种很暴力的方式。

    public static void test02(){
        Thread thread1 = new Thread(()->{
            System.out.println("thread1启动了");
            while (true){
                System.out.println("thread1循环中...");
            }
        });
        thread1.start();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("准备关闭thread1线程");
        thread1.stop();

        System.out.println("主线程停止");
    }

运行结果如下

在这里插入图片描述

使用线程的interrupt()来中断线程

    public static void testInterrupt(){
        Thread thread1 = new Thread(() -> {
            while (true){
                boolean interrupted = Thread.currentThread().isInterrupted();
                if(interrupted){
                    System.out.println("thread1线程被中断");
                    break;
                }
                System.out.println("thread1循环中...");
            }
        });

        thread1.start();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        thread1.interrupt();
    }

运行结果如下

在这里插入图片描述

interrupt相比于stop中断线程的方式更加温柔,当主线程调用thread1线程的interrupt方法其实本质就是将thread1线程的中断标志设置为true,仅此而已。被设置中断标志的线程还是可以继续运行的,不受影响,也就是如果thread不主动结束线程该线程是不会停止的。
代码演示如下

    public static void testInterrupt2(){
        Thread thread1 = new Thread(() -> {

            while (true){
                boolean interrupted = Thread.currentThread().isInterrupted();
                System.out.println("当前中断标志位状态为:"+interrupted);
                System.out.println("thread1循环中...");
            }
        });

        thread1.start();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        thread1.interrupt();
    }

运行结果如下

在这里插入图片描述

当调用了thread1.interrupt();之后thread1还会一直无限执行下去。

如果thread1线程处于被阻塞状态(例如处于sleep,wait,join等状态),在别的线程调用thread1的interrupt方法,那么线程的中断状态会被清除,并抛出InterruptedException异常

代码如下

    public static void testInterrupt3(){
        Thread thread1 = new Thread(() -> {
            System.out.println("thread1线程启动了。。。");
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        });

        thread1.start();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        thread1.interrupt();
    }

运行结果如下

在这里插入图片描述

1.线程启动是,默认中断标志位为false
2.如果main线程调用了thread1的interrupt()方法,中断标志位就变成了true
3.正常情况,中断标志位为true,如果thread1判断中断标志位为true就中断执行,则thread1停止,如果thread1线程自己不终止运行则不会停止。
4.异常情况,如果thread1线程正处于阻塞状态(例如处于sleep,wait,join等状态),将会把中断状态清除,并且将抛出InterruptedException异常,此时中断标志位还是false,thread1线程还会继续执行。

测试异常情况,并且循环不停止的情况,代码如下

    public static void testInterrupt4(){
        Thread thread1 = new Thread(() -> {
            System.out.println("thread1线程启动了。。。");
            try {
                Thread.sleep(5000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            while (true){
                boolean interrupted = Thread.currentThread().isInterrupted();
                if(interrupted){
                    System.out.println("thread1程序终止");
                    break;
                }
            }
        });

        thread1.start();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        thread1.interrupt();
    }

在这里插入图片描述

程序并没有停止

5.解决异常情况的方法,就是在catch块中,需要再次将中断标志位设置为true,2次调用才能使中断标志位改为true

    public static void testInterrupt5(){
        Thread thread1 = new Thread(() -> {
            System.out.println("thread1线程启动了。。。");
            try {
                Thread.sleep(5000);
            } catch (Exception e) {
	            // 抛出异常过后在此调用interrupt方法
                Thread.currentThread().interrupt();
                e.printStackTrace();
            }
            while (true){
                boolean interrupted = Thread.currentThread().isInterrupted();
                if(interrupted){
                    System.out.println("thread1程序终止");
                    break;
                }
            }
        });

        thread1.start();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        thread1.interrupt();
    }

在这里插入图片描述

关于Thread.interrupted()方法

判断线程是否被中断并清除当前中断状态
这个方法做了两件事情
1.返回当前线程的中断状态
2.将当前线程的中断状态清零并重新设置为false,清除线程的中断状态

    public static void testInterrupt6(){
        System.out.println(Thread.currentThread().getName() + "\t" + Thread.interrupted());
        System.out.println(Thread.currentThread().getName() + "\t" + Thread.interrupted());
        System.out.println("1111111111111111");

        // 中断标志位设置为true
        Thread.currentThread().interrupt();

        System.out.println("2222222222222222");
        System.out.println(Thread.currentThread().getName() + "\t" + Thread.interrupted());
        System.out.println(Thread.currentThread().getName() + "\t" + Thread.interrupted());

    }

在这里插入图片描述

关于isInterrupted()方法

该方法只会返回当前线程的中断标志位的状态;不会清除当前线程的中断标志位的状态

    public static void testInterrupt7(){
        System.out.println(Thread.currentThread().getName() + "\t" + Thread.currentThread().isInterrupted());
        System.out.println(Thread.currentThread().getName() + "\t" + Thread.currentThread().isInterrupted());
        System.out.println("1111111111111111");

        // 中断标志位设置为true
        Thread.currentThread().interrupt();

        System.out.println("2222222222222222");

        System.out.println(Thread.currentThread().getName() + "\t" + Thread.currentThread().isInterrupted());
        System.out.println(Thread.currentThread().getName() + "\t" + Thread.currentThread().isInterrupted());
    }

在这里插入图片描述

关于Thread的静态方法interrupted和Thread实例方法isInterrupted底层源码

1.interrupted

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

2.isInterrupted

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

本质上都是调用了实例的isInterrupted方法,只是传入的参数有所不同,当传入true时,会情空当前线程的中断标志,重置为false,方传入false时,不会清空。

private native boolean isInterrupted(boolean ClearInterrupted);

该方法是被native修饰的方法

总结

通过共享变量来控制

1.使用volatile 关键字来实现线程中断

    static volatile boolean run = true;
    public static void main(String[] args) {
        new Thread(()->{
            while (run){
                System.out.println("线程1执行中...");
            }
        }).start();

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        run = false;
        System.out.println("主线程结束");
    }

2.使用同步代码块synchronized来实现线程中断

    static boolean run = true;
    static Object object = new Object();
    public static void main(String[] args) {
        new Thread(()->{
            while (run){
                System.out.println("线程1执行中...");
                synchronized (object){

                }
            }
        }).start();

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        run = false;
        System.out.println("主线程结束");
    }

3.使用AtomicBoolean 来实现线程中断

    public static void main(String[] args) {

        AtomicBoolean run = new AtomicBoolean(true);
        new Thread(()->{
            while (run.get()){
                System.out.println("线程1执行中...");
            }
        }).start();

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        run.set(false);
        System.out.println("主线程结束");
    }

其运行结果如下

在这里插入图片描述

到此这篇关于Java中线程中断的几种方法小结的文章就介绍到这了,更多相关Java 线程中断内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文