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

多线程唤醒问题

public class FlagWork {
    public static void main(String[] args) {
        final Business1 b1 = new Business1();
        new Thread(new Runnable() {
 
            @Override
            public void run() {
                b1.a();
            }
        }).start();
        new Thread(new Runnable() {
 
            @Override
            public void run() {
                b1.b();
            }
        }).start();
        new Thread(new Runnable() {
             
            @Override
            public void run() {
                b1.c();
            }
        }).start();
    }
}
 
class Business1 {
    private int flag = 1;
 
    public void a() {
        for (int i = 0; i < 50; i++) {
            synchronized (this) {
                while (flag != 1) {
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                for (int j = 1; j <= 10; j++) {
                    System.out.println("线程a运行" + j + "次");
                }
                flag = 2;
                this.notify();
            }
        }
    }
 
    public void b() {
        for (int i = 0; i < 50; i++) {
            synchronized (this) {
                while (flag != 2) {
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                for (int j = 1; j <= 20; j++) {
                    System.out.println("线程b运行" + j + "次");
                }
                flag = 3;
                this.notify();
            }
        }
    }
    public void c() {
        for (int i = 0; i < 50; i++) {
            synchronized(this){
                while(flag!=3){
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                for (int j = 1; j <= 30; j++) {
                    System.out.println("线程c运行"+j+"次");
                }
                flag = 1;
                this.notifyAll();
            }
        }
    }
}

A线程先运行10次,然后B线程运行20次,然后C线程运行30次,如此反复50次的代码,为什么次c方法里要用this.notifyAll,而用this.notify就不行

正在回答

4 回答

三个方法里至少有一个是notifyAll。假设三个都是notify(),当方法c运行完后,flag为1,此时如果a和b都已经在Wait Set中,且随机唤醒的是b,那么b随机又进入Wait set,c也进入Wait set,此时三个线程全部进入Wait set,造成了死锁。

0 回复 有任何疑惑可以回复我~
#1

_Everglow 提问者

贼六
2017-02-09 回复 有任何疑惑可以回复我~

哈哈  确实??

0 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消

多线程唤醒问题

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信