Java - 使用wait()和notify()

标签 java multithreading deadlock

这不是 Java, Multithreading with synchronized methods 的重复项...他没有问同样的问题。

我正在尝试编写一个使用多线程和死锁的程序。我无法理解在同步方法中如何以及在何处使用 wait() 和 notify() 来让线程等待并使用 notification() 唤醒它。我让第一个线程在 ping 语句之后等待,这样下一个线程也将启动它的 ping 语句。但我有一个notify()来唤醒第一个线程,但我不明白为什么该线程不会唤醒。以下应该是我的输出:

Starting...1
Girl (ping): pinging Boy
Boy (ping): pinging Girl
Girl (ping): asking Boy to confirm
Boy (confirm): confirm to Girl
Girl (ping): got confirmation
Boy (ping): asking Girl to confirm
Girl (confirm): confirm to Boy
Boy (ping): got confirmation

我的代码死锁或者我没有正确使用等待和通知,因为它停在这里:

Starting...1
Girl (ping): pinging Boy
Boy (ping): pinging Girl
Girl (ping): asking Boy to confirm
Boy (confirm): confirm to Girl
Girl (ping): got confirmation

这是我的代码:

监视器.java

class Monitor {
String name;

   public Monitor (String name) { this.name = name; }

   public String getName() {  return this.name; }

   public synchronized void ping (Monitor p) {
      p.release(p);
      System.out.println(this.name + " (ping): pinging " + p.getName());
      notify();
      try { wait(); } catch (Exception e) {}
      System.out.println(this.name + " (ping): asking " + p.getName() + " to confirm");
      p.confirm(p);
      System.out.println(this.name + " (ping): got confirmation");
   }

   public synchronized void confirm (Monitor p) {
      System.out.println(this.name + " (confirm): confirm to " + p.getName());
   }

   public synchronized void release (Monitor p) {
      notify();
   }
}

Runner.java

public class Runner extends Thread {
Monitor m1, m2;

    public Runner (Monitor m1, Monitor m2) { 
      this.m1 = m1; 
      this.m2 = m2; 
    }

    public void run () {  
       m1.ping(m2);  
    }
}

死锁.java

public class DeadLock {
   public static void main (String args[]) {
      int i=1;
      System.out.println("Starting..."+(i++));
      Monitor a = new Monitor("Girl");
      Monitor b = new Monitor("Boy");
      (new Runner(a, b)).start();
      (new Runner(b, a)).start();
   }
}

最佳答案

您正在调用:

(new Runner(a, b)).start();
// which effectively calls in run()
a.ping(b);

这会锁定a,在a上调用notify,然后等待a

其他线程调用:

(new Runner(b, a)).start();
// which effectively calls in run()
b.ping(a);

这会锁定 b 调用 b 上的通知,然后等待 b

由于两个线程都没有通知另一个线程,因此它们永远不会离开该状态。我不确定您想要完成什么,因此很难弄清楚如何修复代码。

编辑:

现在您已经编辑了代码,您遇到了更标准的死锁。

  • 第一个线程锁定 a,然后尝试锁定 b 以通知它。
  • 第二个线程锁定 b,然后尝试锁定 a 以通知它。

每个线程都有自己的锁,但需要另一个锁才能继续。经典的僵局。

我建议你学习使用调试器@OhioState22。设置断点并单步执行代码。这是一个不错的Eclipse tutorial .

关于Java - 使用wait()和notify(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14390257/

相关文章:

python - Python 中的线程,参数发送到线程

Java——利用SWAP函数解决互斥死锁

java - Libgdx 光标捕获后消失

java - 写入由 ClassLoader 加载的 Wildfly 上的属性文件

java - 如何阻止 SpeechSynthesis.speak(String) ?

java - 在 Android 中的单独线程上使用循环器

java - 如何让 HA Proxy 自己跟随重定向?

java - Switch 语句和不兼容的类型?

java网络接受线程之间的网络连接

mysql - 使用 IN(,,,) 生成的行锁会产生死锁吗?