Reputation: 43
THIS IS NOT A DUPLICATE OF Java, Multithreading with synchronized methods... he didn't ask the same question.
I am trying to write a program that using multi-threading and deadlocks. I am having trouble understanding how and where to use wait() and notify() in my synchronized methods to have the thread wait and wake it up with notify(). I have it to make the first thread wait after the ping statement so the next thread will start it's ping statement too. But I have a notify() to wake up the first thread and I can't figure out why the thread will not wake up. The following is suppose to be my output:
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
My code is deadlocking or I am not using wait and notify correctly because it stops here:
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
Here is my code:
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();
}
}
Upvotes: 0
Views: 445
Reputation: 116908
You are calling:
(new Runner(a, b)).start();
// which effectively calls in run()
a.ping(b);
This locks a
calls notify on a
and then waits on a
.
The other thread calls:
(new Runner(b, a)).start();
// which effectively calls in run()
b.ping(a);
This locks b
calls notify on b
and then waits on b
.
Since neither of the threads is notifying the other one, they will never leave that state. I'm not sure what you are trying to accomplish so it's hard to figure out how to fix the code.
Edit:
Now that you've edited your code you have a more standard deadlock.
a
then tries to lock b
to notify it.b
then tries to lock a
to notify it.Each thread has their lock but needs the other lock to continue. Classic deadlock.
I suggest that you learn to use the debugger @OhioState22. Set break points and step through your code. Here's a decent Eclipse tutorial.
Upvotes: 1
Reputation: 3915
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
Upvotes: 0