Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java for newbies - DeadLock imitation

I'm trying to write very simple program which will imitate simple DeadLock, where Thread A waits for Resource A locked by Thread B and Thread B waits for Resource B locked by Thread A.

Here is my code:

//it will be my Shared resource
public class Account {
    private float amount;

    public void debit(double amount){
        this.amount-=amount;
    }

    public void credit(double amount){
        this.amount+=amount;
    }

}  

This is my runnable which performs Operation on the resource above:

public class BankTransaction implements Runnable {
    Account fromAccount,toAccount;
    float ammount;
    public BankTransaction(Account fromAccount, Account toAccount,float ammount){
        this.fromAccount = fromAccount;
        this.toAccount = toAccount;
        this.ammount = ammount;
    }

    private void transferMoney(){
        synchronized(fromAccount){
            synchronized(toAccount){
                fromAccount.debit(ammount);
                toAccount.credit(ammount);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                e.printStackTrace();
                }
                System.out.println("Current Transaction Completed!!!");
            }
        }
    }

    @Override
    public void run() {
        transferMoney();
    }

}

and finally my main class:

    public static void main(String[] args) {

    Account a = new Account();
    Account b = new Account();
    Thread thread1 = new Thread(new BankTransaction(a,b,500));

    Thread thread2 = new Thread(new BankTransaction(b,a,500));
       thread1.start();  
       thread2.start();  
System.out.println("Transactions Completed!!!");

    }
}

Why does this code run execute successfully and I don't have and deadLock?

like image 271
danny.lesnik Avatar asked Aug 23 '11 22:08

danny.lesnik


2 Answers

It's got the potential for deadlock - but both locks are acquired so quickly together that one thread can get both before the other has the chance to acquire its first one.

Put another Thread.sleep(500); call between the two synchronized statements and it does deadlock: both threads will enter "their" outer lock, sleep, then when they wake up they'll both find that their "inner" lock is already acquired.

This is due to the fact that you synchronized statements are anti-symetrical : for one thread, the outer synchronized lock is the inner one for the other thread and the other way around.

like image 90
Jon Skeet Avatar answered Sep 24 '22 09:09

Jon Skeet


It's possible that one of the threads will enter both synchronized sections, blocking the other thread entirely until it's finished.

like image 43
Oliver Charlesworth Avatar answered Sep 24 '22 09:09

Oliver Charlesworth