0

这不是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

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

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();
   }
}

亚军.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();
   }
}
4

2 回答 2

1

您正在调用:

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

这锁定a调用 notify ona然后等待a

另一个线程调用:

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

这锁定b调用 notify onb然后等待b

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

编辑:

现在你已经编辑了你的代码,你就有了一个更标准的死锁。

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

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

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

于 2013-01-18T00:16:30.537 回答
0

As a rule avoid using Java's wait() and notify() and prefer one of Java 5's concurrency features instead, e.g. ReentrantLock. The reason is that if a thread calls notify() before your thread hits wait(), the subsequent call to wait() will block and depending on your algorithm, indefinitely. Lookup the javadocs for RenetrantLock

于 2013-01-18T00:51:19.817 回答