Question

In: Computer Science

Why is this java code reaching a deadlock and how to I fix it without serializing...

Why is this java code reaching a deadlock and how to I fix it without serializing the code (i.e. I don't want to do not have the Girl authenticate the Boy then have the Boy authenticate the Girl)?


import java.applet.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

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

Solutions

Expert Solution

Some detail before I answer your questions:

This piece of code will not alway get stuck into the deadlock. It will only happen when both Threads tries to execute ping() method at the very same instance(sounds bizarre).

Two threads have been started immediately one after another and so it is easy to assume that they will always execute ping() method simultaneously(Boy and girl Monitor both), but that wont always be the case, one thread will seldom complete execution of method ping() before the other starts as it has very small footprint. And so in that case the code will run as expected.

So why in some cases it gets stuck into deadlock?
The reason is the use of synchronized keyword in method syntax. A synchronized method gets lock on the current object('this') before starting the execution of the method. What does that mean exactly?

public synchronized void ping(Monitor p) {

...
}

is essentially,

public void ping(Monitor p) {

        synchronized (this) {
        ......

        }

}

Which means that when m1.ping(m2) is called from Thread1 the ping() method will get hold of the lock on 'this' object(which would be m1 in this case). So, consequently no other synchronized method of 'this(m1)'s can be called until ping() releases the lock on 'this'(on m1). Now, ping() is also calling a synchronized method from within itself, albeit, some other objects(m2)'s confirm() method. Same rule would apply there also. ping() method of 'this' (m1) would want to execute m2's confirm(), BUT what if some other thread(Thread2) is doing the same with m2, i.e. calling the ping() method of m2, so holding the lock on m2. Which means m1('this') will have to wait until m2's ping() releases lock on it. BUT m2's ping() wont be able to do it as m1's confirm() cant be executed from there within as m1's ping() already has a lock on m1, ergo a deadlock.

To prevent this,

Remove dependancy of 'this' as a single lock to call both the methods of single object. What does that mean? Create two different objects that holds lock on both methods respectively. This will make sure that no two thread can execute ping() simultaneously(while same applies for confirm()), but they will not hold each other's execution(ping() and confirm() of same object can be called independently from different thread). here's the implementation.

public class Monitor {
    String name;
    final Object pingLock = new Object();
    final Object confirmationLock = new Object();

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

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

    public void ping(Monitor p) {
        synchronized (pingLock) {
            System.out.println(this.name + " (ping): pinging " + p.getName());
            p.confirm(this);
            System.out.println(this.name + " (ping): got confirmation");
        }

    }

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


Related Solutions

JAVA: How do I fix the last "if" statement in my code so that outputs the...
JAVA: How do I fix the last "if" statement in my code so that outputs the SECOND HIGHEST/MAXIMUM GPA out of the given classes? public class app { private static Object minStudent; private static Object maxStudent; public static void main(String args[ ]) { student st1 = new student("Rebecca", "Collins", 22, 3.3); student st2 = new student("Alex", "White", 19, 2.8); student st3 = new student("Jordan", "Anderson", 22, 3.1); student[] studentArray; studentArray = new student[3]; studentArray[0] = st1; studentArray[1] = st2; studentArray[2]...
Hello I have this error in the code, I do not know how to fix it....
Hello I have this error in the code, I do not know how to fix it. It is written in C++ using a Eclipse IDE Error: libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: basic_string bus.h =========== #pragma once #include using namespace std; class Bus { private:    string BusId; // bus ID    string Manufacturer; // manufacturer of the bus    int BusCapacity; // bus capacity    int Mileage; // mileage of bus    char Status; // current status...
I already have the code of this program, I just want to know how to fix...
I already have the code of this program, I just want to know how to fix the code to Implement the 5th function (System.nanotime() and System.currentTimeMillis() methods) What Code does: Introduction Searching is a fundamental operation of computer applications and can be performed using either the inefficient linear search algorithm with a time complexity of O (n) or by using the more efficient binary search algorithm with a time complexity of O (log n). Task Requirements In this lab, you...
I Have posted my Java code below. Fix the toString, add, and remove implementations so that...
I Have posted my Java code below. Fix the toString, add, and remove implementations so that the following test cases work. Note: I have removed all the unnecessary inherited List implementations. I have them to: throw new UnsupportedException(); For compilation, you could also add //TODO. Test (Main) List list = new SparseList<>(); list.add("0"); list.add("1"); list.add(4, "4"); will result in the following list of size 5: [0, 1, null, null, 4]. list.add(3, "Three"); will result in the following list of size...
I'm getting an error message with this code and I don't know how to fix it...
I'm getting an error message with this code and I don't know how to fix it The ones highlighted give me error message both having to deal Scanner input string being converted to an int. I tried changing the input variable to inputText because the user will input a number and not a character or any words. So what can I do to deal with this import java.util.Scanner; public class Project4 { /** * @param args the command line arguments...
Can you fix this code please. the removing methods id no doing anything. this is java...
Can you fix this code please. the removing methods id no doing anything. this is java code import java.util.NoSuchElementException; public class DoublyLinkedList<E> {    public int size;    public Node head;    public Node tail;             @Override    public boolean isEmpty() {               return size == 0;    }    @Override    public int getSize() {               return 0;    }    @Override    public void addAtFront(E element) {       ...
The source code I have is what i'm trying to fix for the assignment at the...
The source code I have is what i'm trying to fix for the assignment at the bottom. Source Code: #include <iostream> #include <cstdlib> #include <ctime> #include <iomanip> using namespace std; const int NUM_ROWS = 10; const int NUM_COLS = 10; // Setting values in a 10 by 10 array of random integers (1 - 100) // Pre: twoDArray has been declared with row and column size of NUM_COLS // Must have constant integer NUM_COLS declared // rowSize must be less...
I need to understand how I would edit this code without changing anything, only adding. I...
I need to understand how I would edit this code without changing anything, only adding. I am not looking for the exact answer, just information on how I would use the given code to complete some of the todo statements. Thank you! // include this header file so we can use `printf()` #include <stdio.h> // every C program must implement the `main()` function int main(int argc, char *argv[]) {    //TODO: check for enough arguments       // save the...
JAVA JAVA JAVA Hey i need to find a java code for my homework, this is...
JAVA JAVA JAVA Hey i need to find a java code for my homework, this is my first java homework so for you i don't think it will be hard for you. (basic stuff) the problem: Write a complete Java program The transport Company in which you are the engineer responsible of operations for the optimization of the autonomous transport of liquid bulk goods, got a design contract for an automated intelligent transport management system that are autonomous trucks which...
Need to fix this code for tc -tac-toe game .. see the code below and fix...
Need to fix this code for tc -tac-toe game .. see the code below and fix it #include <iostream> using namespace std; void display_board(); void player_turn(); bool gameover (); char turn ; bool draw = false; char board [3][3] = { {'1', '2', '3'}, { '4', '5', '6'}, { '7', '8', '9'}}; int main() { cout << " Lets play Tc- Tac- toe game " <<endl ; cout << " Player 1 [X] ----- player 2 [0] " <<endl <<endl;...
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT