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

关于Java多线程遇到的问题.

关于Java多线程遇到的问题.

元芳怎么了 2019-03-20 17:19:20
1.最近在学习Java多线程,看到视频中要实现一个类似闹钟和小明的情景, 要求闹钟响,小明关闹钟, 三秒后闹钟再响,小明再关, 重复10次程序结束. 不知道为什么我的程序小明只能输出一次.public class Test {    public static void main(String[] args) {        Clock ck = new Clock();        new XiaoMing(ck);    }}public class Clock implements Runnable{    public Boolean isAlarm;    public Boolean shutdown;    public Clock() {        isAlarm = false;        shutdown = false;        new Thread(this).start();    }    @Override    public void run() {        for (int i = 0; i < 10; i++) {            isAlarm = true;            System.out.println("Get up * 3 !");            synchronized (this) {                notifyAll();                try {                    wait(3000);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }        shutdown = true;    }}public class XiaoMing implements Runnable{    private Clock clk;    public XiaoMing(Clock clk) {        this.clk = clk;        new Thread(this).start();    }    @Override    public void run() {        while(true) {            if (clk.isAlarm) {                System.out.println("Woshixiaoming!");                clk.isAlarm = false;                synchronized (this) {                    try {                        wait();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }            else{                if(clk.shutdown)    break;            }        }    }}输出结果如下Get up * 3 !Woshixiaoming!Get up * 3 !Get up * 3 !...(10 次 Getup, 之后程序停在那里)
查看完整描述

1 回答

?
一只斗牛犬

TA贡献1784条经验 获得超2个赞

这是因为你没有理解到wait(),notify(),notifyAll()这三个方法的真正作用,它们不是控制的所有线程,而是所对象的线程。
也就是说,XiaoMing 的同步锁里调用的 wait() 方法阻塞的是 XiaoMing 这个线程;Clock 的同步锁唤醒的是 Clock 类的对象的线程,所以 XiaoMing 的对象的线程就一直阻塞下去了
可以修改 XiaoMing 类run()方法的同步锁

@Override

    public void run() {

        while(true) {

            if (clk.isAlarm) {

                System.out.println("Woshixiaoming!");

                clk.isAlarm = false;

                synchronized (this.clk) {

                    try {

                        this.clk.wait();

                    } catch (Exception e) {

                        e.printStackTrace();

                    }

                }

            }

            else{

                if(clk.shutdown)    break;

            }

        }

    }

这样 XiaoMing 的线程会因为clk域被阻塞,直到Clock的线程调用notifyAll()

查看完整回答
反对 回复 2019-04-17
  • 1 回答
  • 0 关注
  • 567 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号