美文网首页Java
【多线程】——3.线程的中断

【多线程】——3.线程的中断

作者: 衰煋 | 来源:发表于2020-03-29 16:02 被阅读0次


    线程中断的概念

    java线程中断是一种协作机制

    通过中断并不能直接终止线程的运行

    需要被中断的线程自己处理中断

    (A通知B进行中断,B不会立刻中断,B会寻找合适的时机进行中断)

    被中断的线程并不是立刻退出运行

    每个线程都有一个boolean类型的标志位,代表线程是否被中断了。

    线程1想要中断线程2,线程1设置线程2的标志位为true就可以了。

    线程2在合适的时候处理该中断请求,甚至可以不处理中断请求。

    线程中断的相关方法

    1.public static boolean interrupted()

    测试这个线程是否已经中断。但是调用这个方法,线程的中断状态也会被清除。

    如果连续两次调用这个方法,第二次调用将返回false。除非两次调用之间当前线程又被中断一次。

    2.public boolean isInterrupted()

    测试这个线程是否已经中断。线程的中断状态不会被影响。

    3.public void interrupt()

    将调用该方法的对象所表示的线程标记一个停止标记,并不是真正的中断该线程。

    public static void main(String[] args) {

        //当前线程

        Thread thread = Thread.currentThread();

        //当前线程是否被中断----【没有,false】

        System.out.println("1:"+thread.isInterrupted());

        //设置线程中断----【中断】

        thread.interrupt();

        //判断线程是否被中断----【被中断了,true】

        System.out.println("2:"+thread.isInterrupted());

        //判断线程是否被中断----【thread.isInterrupted() 没有改变线程中断标志位,还是true】

        System.out.println("3:"+thread.isInterrupted());

        try {

            //----【休眠2秒,但是线程被中断了,所以报错】

            Thread.sleep(2000);

            //----【不走这里,被catch了】

            System.out.println("not Interrupted");

        } catch (InterruptedException e) {

            //----【被catch后,程序运行到这里】

            System.out.println("Thread.sleep Interrupted");

            //判断线程是否被中断----【线程标志位变为false,代表线程没有被中断,意味着如果希望继续中断,要手工中断处理】

            System.out.println("4:"+thread.isInterrupted());

        }

        //----【标志位显示没有被中断】

        System.out.println("5:"+thread.isInterrupted());

    }

    返回结果

    1:false

    2:true

    3:true

    Thread.sleep Interrupted

    4:false

    5:false

    interrupt()方法是唯一一个可以将线程中断状态设置为true的方法

    静态方法interrupted()会将当前线程的中断状态清除。

    中断的处理

    1.方法声明中有抛出InterruptedEception则表示该方法是可以中断的

    2.常见的抛出InterruptedEception异常的方法

    Object.wait()

    Thread.sleep()

    BlockQueue.put()

    BlockQueue.take()

    抛出InterruptedEception

    如果抛出InterruptedEception意味着一个方法是阻塞方法

    那么调用一个阻塞方法意味着你的方法也是阻塞方法

    通常最容易的策略就是自己抛出InterruptedEception

    重新中断

    有时候代码里面抛InterruptedEception不合适

    Runnable接口的run()方法不允许抛出异常

    如果线程运行中出现了InterruptedEception,又不能抛出异常

    直接捕获异常可能又没办法通知上层代码,又不能保留中断证据

    比较好的方式是再次调用interrupt()方法重新中断、

    总结

    1.子线程等待特定的条件到来后继续执行,如果特定条件提前到来,可以通过中断通知子线程

    比如:Thread.sleep(10000)预计休眠10s,但是特定条件提前到来,通知sleep线程

    2.线程调用join()阻塞自己子线程执行结束,子线程假设要耗时很久,没办法短时间内执行完,可以通过线程中断告诉主线程,我(子线程)要很久才能执行完,你(主线程)别等了。

    3.线程中断只是一种协作机制,不能立马中断,被中断的线程在合适的时机才会被中断。

    4.频繁的检测线程是否被中断,会导致效率很低下

    5.较少的检查可能得不到及时的响应

    相关文章

      网友评论

        本文标题:【多线程】——3.线程的中断

        本文链接:https://www.haomeiwen.com/subject/ojluuhtx.html