繁体   English   中英

Java-使用wait()和notify()

[英]Java - using wait() and notify()

这不是Java的重复, 带有同步方法的多线程 ...他没有问同样的问题。

我正在尝试编写一个使用多线程和死锁的程序。 我无法理解在同步方法中如何以及在何处使用wait()和notify()来让线程等待并通过notify()将其唤醒。 我让第一个线程在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

我的代码陷入僵局,或者我没有使用wait并正确通知,因为它在这里停止:

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

这是我的代码:

Monitor.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);  
    }
}

Deadlock.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 ,然后等待上a

其他线程调用:

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

这将锁定bb上调用notify,然后在b上等待。

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

编辑:

现在,您已经编辑了代码,您将拥有一个更加标准的死锁。

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

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

我建议您学习使用调试器@ OhioState22。 设置断点并逐步执行代码。 这是一个不错的Eclipse教程

通常,请避免使用Java的wait()和notify(),而是改用Java 5的并发功能之一,例如ReentrantLock。 原因是,如果线程在线程到达wait()之前调用notify(),则后续对wait()的调用将无限期地阻塞,具体取决于您的算法。 Javadocs中查找RenetrantLock

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM