试图让守卫的块工作

丹尼尔·施罗德·德夫

我不明白为什么我的代码无法正常工作。我希望第一个线程等待4秒钟,以便第二个线程将共享布尔值“ joy”设置为true,然后让第一个线程打印出“ Joy已经实现!”。

运行代码时,得到以下输出:

“还没有喜悦……”

“通知喜悦”

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

我正在从Oracle的“ The Java Tutorial”(第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();
    }
}
迪米塔尔·迪米特罗夫(Dimitar Dimitrov)

您正在呼叫,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!");
   }
}

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章