Java, multithreading with synchronized methods

I have problems with the fact that my program sometimes does not come to a standstill. I think I need to add a third synchronized release of the method, which can be used to release another thread after a ping call. code below.

// Attempt at a simple handshake.  Girl pings Boy, gets confirmation.
// Then Boy pings girl, get confirmation.
class Monitor {
    String name;

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

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

     // Girl thread invokes ping, asks Boy to confirm.  But Boy invokes ping,
    // and asks Girl to confirm.  Neither Boy nor Girl can give time to their
    // confirm call because they are stuck in ping.  Hence the handshake 
    // cannot be completed.
    public synchronized void ping (Monitor p) {
      System.out.println(this.name + " (ping): pinging " + p.getName());
      p.confirm(this);
      System.out.println(this.name + " (ping): got confirmation");
    }

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

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

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();
    }
}
+5
source share
2 answers

When an operation needs to get two different locks, the only way to make sure there are no deadlocks is to make sure that each thread trying to perform these operations gets a lock for several objects in the same order.

To fix the deadlock, you need to change the code like this - not really, but it works.

 public void ping (Monitor p) {
  Monitor one = this;
  Monitor two = p;
  // use some criteria to get a consistent order
  if (System.identityHashCode(one) > System.identityHashCode(two)) {
    //swap
    Monitor temp = one;
    one = two;
    two = one;
  }
  synchronized(one) {
       synchronized(two) {
           System.out.println(this.name + " (ping): pinging " + p.getName());
           p.confirm(this);
           System.out.println(this.name + " (ping): got confirmation");
        }
  }
}
+6
source

. Monitor.name volatile . : final. synchronized . "", , .

, . , . , . , . , ; .

- , . , , . .

0

All Articles