【问题标题】:Trying to Get Guarded Blocks to Work试图让受保护的块工作
【发布时间】:2016-04-23 23:03:47
【问题描述】:

我不明白为什么我的代码不能正常工作。我希望第一个线程等待 4 秒,让第二个线程将共享布尔值“joy”设置为 true,然后第一个线程打印出“Joy has been implemented!”。

当我运行代码时,我得到这个输出:

“还没有快乐……”

“通知喜悦”

然后它会冻结并且不会继续。如果我的理解是正确的,从我的 notifyJoy() 方法调用的 notifyAll() 方法应该将 t1 从它的 wait() 中唤醒,然后,由于共享的静态布尔变量 joy 现在为真,“Joy 已经实现了!”应该打印到控制台。

我正在阅读 Oracle 的“Java 教程”第 13 章:这里是特定部分的链接:Java Tutorial Website。我要摆脱他们所拥有的并举一个小例子,但我似乎无法弄清楚我做错了什么。任何帮助,将不胜感激。这是我的代码的完整副本供您参考:

public class JoyTime {

    public static void main(String[] args) {
        JoyRider j1 = new JoyRider(false);
        JoyRider j2 = new JoyRider(true);

        Thread t1 = new Thread(j1, "J1");
        Thread t2 = new Thread(j2, "J2");

        t1.start();

        try {
            Thread.sleep(4000);
        }
        catch (InterruptedException e) {}

        t2.start();
    }
}

class JoyRider implements Runnable {

    private static boolean joy = false;
    private boolean flag;

    public JoyRider(boolean flag) {
        this.flag = flag;
    }

    @Override
    public void run() {
        synchronized(this) {
            if (flag) {
                notifyJoy();
            }
            else {
                while (!joy) {
                    System.out.println("No Joy Yet...");
                    try {
                        this.wait();
                    }
                    catch (InterruptedException e) {}
                }
                System.out.println("Joy has been achieved!");
            }
        }
    }

    public synchronized void notifyJoy() {
        System.out.println("Notifying Joy");
        joy = true;
        notifyAll();
    }
}

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    您在不同的监视器上调用wait()notifyAll(),更具体地说是在两个不同JoyRider 实例的内置监视器上。

    如果引入专用的锁对象:

    private static final Object LOCK = new Object();

    并稍微更改您的 run() 方法:

    synchronized (LOCK) {
       if (flag) {
          System.out.println("Notifying Joy");
          JOY = true;
          LOCK.notifyAll();
       }
       else {
          while (!JOY) {
             System.out.println("No Joy Yet...");
             try {
                LOCK.wait();
             }
             catch (InterruptedException e) {}
          }
          System.out.println("Joy has been achieved!");
       }
    }
    

    您应该能够以正确的顺序看到所有预期的打印。

    【讨论】:

      猜你喜欢
      • 2018-03-11
      • 2018-05-29
      • 2015-05-16
      • 2016-11-24
      • 2010-11-17
      • 1970-01-01
      • 1970-01-01
      • 2016-11-27
      • 1970-01-01
      相关资源
      最近更新 更多