开发者社区> 问答> 正文

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

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, 之后程序停在那里)

展开
收起
蛮大人123 2016-03-11 18:46:14 2150 0
2 条回答
写回答
取消 提交回答
  • 楼主你的Clock 方法也个问题,你的程序逻辑是clock唤醒->XiaoMing等待,然而在第十次循环结束后,XiaoMing没有迎来第十一次的唤醒让他break出去,一直在默默等待,修改后Clock的run方法如下:

    @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;
            synchronized (this) {
                notifyAll();
            }
        }
    2019-07-17 18:59:54
    赞同 展开评论 打赏
  • 我说我不帅他们就打我,还说我虚伪

    这是因为你没有理解到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-07-17 18:59:54
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载