试图让守卫的街区工作
我不明白为什么我的代码工作不正常。 我希望第一个Thread等待4秒,第二个Thread将共享布尔“joy”设置为true,然后第一个Thread打印出“Joy已经实现!”。
当我运行代码时,我得到这个输出:
“没有喜悦……”
“通知喜悦”
然后它冻结并且不会继续。 如果我的理解是正确的,从我的notifyJoy()方法调用的notifyAll()方法应该从它的wait()唤醒t1然后,因为共享的静态布尔变量joy现在是真的,“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(); } }
您在不同的监视器上调用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!"); } }
您应该能够以正确的顺序看到所有预期的打印件。
首先查看notifyAll
的文档 。
唤醒等待此对象监视器的所有线程。
强调我的。 你有两个JoyRider
, j1
和j2
。 他们每个人都在wait
自己。 因此,当您调用notifyAll
,您只是通知在该实例上等待的线程(即, j1
仅通知在j1
上等待的线程,并且j2
仅通知在j2
上等待的线程)。
您可以通过同步和锁定静态对象来解决此问题。 所以添加private static final Object LOCK = new Object();
,将您的方法更改为synchronize(LOCK)
,并调用notifyAll
并wait
LOCK
而不是this
。