java - 尝试让 protected block 正常工作

标签 java multithreading

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

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

"No Joy Yet..."

"Notifying Joy"

然后它就卡住了并且不再继续。如果我的理解是正确的,从我的notifyJoy()方法调用的notifyAll()方法应该将t1从wait()中唤醒,然后,由于共享静态 boolean 变量joy现在为true,“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();
    }
}

最佳答案

您正在调用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!");
   }
}

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

关于java - 尝试让 protected block 正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36817437/

相关文章:

java - 如何将数据从文本文件导入到 JTextArea?

c# - 线程本地存储

android - android间隔怎么样

java - 对单个进程集体使用多个线程

java - 使用文件参数通过 Java 运行 python 脚本

java - Java 中的打印 - Printable.print() 调整图像大小

c - 让所有的 child 从另一个 child 线程 sleep

c# - C#:Thread.Sleep无法正常工作

java - Spring MVC 域对象处理最佳实践

java - 在 Spring Security Oauth2 中使用 RemoteTokenServices 配置资源服务器