Troubleshooting and fixing deadlock

Ravi :

I came across this question recently where I am suppose to find the deadlock in the code present below. I have no experience with Java or multithreading, that's why I am here to understand the problem better.

public class BankAccount {
  private final int customerId;
  private int balance;

  public BankAccount(int customerId, int openingBalance) {
    this.customerId = customerId;
    this.balance = openingBalance;
  }

  public void withdraw(int amount) throws OverdrawnException {
    if (amount > balance) {
      throw new OverdrawnException();
    }
    balance -= amount;
  }

  public void deposit(int amount) {
    balance += amount;
  }

  public int getCustomerId() {
    return customerId;
  }



  public int getBalance() {
    return balance;
  }
}


class TransferOperation extends Thread {
    int threadNum;

    TransferOperation(int threadNum) {
        this.threadNum = threadNum;
    }

    private void transfer(BankAccount fromAccount, BankAccount toAccount, int transferAmount) throws OverdrawnException {
        synchronized (fromAccount) {                    
            synchronized (toAccount) {
                fromAccount.withdraw(transferAmount);
                toAccount.deposit(transferAmount);
            }
        }
    }

    // ...
}

I have this above piece of code. I want to find where a deadlock could occur in the above code. I think only place it could occur is in the two synchronized blocks. Am I right?

If yes, can someone help me understand why? I can guess that it is probably because withdraw and deposit keeps one thread waiting for another. But this is a total guess, that's why asking for help here.

Also if I would want to prevent the deadlock, how would I go about it in the code?

Any help appreciated.

krokodilko :

You are synchronize on fromAccount then toAccount objects.

Imagine that first thread calls transfer method with X,Y, while at the same time the other thread calls the same method with Y,X arguments - this leads to the deadlock.

The first thread "locks" X, the second thread "locks" Y, then the first thread are trying to lock Y, which is already locked by the second thread.
But the second thread is trying to lock X which is already locked by the first thread.
This is a deadlock.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=69259&siteId=1