为了账号安全,请及时绑定邮箱和手机立即绑定

同时执行Thread.interrupt() Object.notify(),为什么会有两个结果?

同时执行Thread.interrupt() Object.notify(),为什么会有两个结果?

UYOU 2022-01-12 16:07:09
public class WaitNotifyAll {    private static volatile Object resourceA = new Object();    public static void main(String[] args) throws Exception {        Thread threadA = new Thread(new Runnable() {            @Override            public void run() {                synchronized (resourceA) {                    try {                        System.out.println("threadA begin wait");                        resourceA.wait();                        System.out.println("threadA end wait");                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        });        Thread threaB = new Thread(new Runnable() {            @Override            public void run() {                synchronized (resourceA) {                    System.out.println("threadC begin notify");                    threadA.interrupt();                    resourceA.notify();                }            }        });        threadA.start();        Thread.sleep(1000);        threaB.start();        System.out.println("main over");    } }这里有两种可能的结果:抛出中断异常正常终止为什么?我不明白。当threadA被中断时,结果应该抛出InterruptedException。但有时执行这个程序,它可以正常完成。环境:java8,mac
查看完整描述

2 回答

?
PIPIONE

TA贡献1829条经验 获得超9个赞

当线程同时接收到中断和通知时,行为可能会有所不同。

请参考https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.2.3

信用 - 并发兴趣邮件列表上的 Alex Otenko


查看完整回答
反对 回复 2022-01-12
?
森栏

TA贡献1810条经验 获得超5个赞

因为重新排序。在正常终止编译器重新排序指令中断和通知中,中断在工作线程上调用并且没有中断异常抛出。尝试通过读取 volatile 变量来禁止重新排序,您总是会遇到异常中断。


public class WaitNotifyAll {

private static volatile Object resourceA = new Object();


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

    Thread threadA = new Thread(new Runnable() {

        @Override

        public void run() {

            synchronized (resourceA) {

                try {

                    System.out.println("threadA begin wait");

                    resourceA.wait();

                    System.out.println("threadA end wait");

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

        }

    });


    Thread threaB = new Thread(new Runnable() {

        @Override

        public void run() {

            synchronized (resourceA) {

                System.out.println("threadC begin notify");

                threadA.interrupt();

                System.out.print(resourceA);

                resourceA.notify();

            }

        }

    });


    threadA.start();


    Thread.sleep(1000);


    threaB.start();


    System.out.println("main over");

}

}


查看完整回答
反对 回复 2022-01-12
  • 2 回答
  • 0 关注
  • 154 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信