CS 252

Concurrency 1 - Lab

The purpose of this lab is to understand locks and deadlocks in Java.

1. Consider this set of classes: Bank.java TransferRunnable.java UnsynchBankTest.java. Run the code to get an idea what the program is doing.

a. What should the total balance of the bank be? Why?

b. Sometimes, the balance is not that amount. Why might you get a printout such as

Thread[Thread-36,5,main] 85.96 from 36 to 4 Total Balance: 99291.06

(There are actually two different reasons. Try to identify both.)

2. Add a lock object to the Bank class:

private Lock bankLock = new ReentrantLock(); // ReentrantLock implements the Lock interface

Use that lock to protect the transfer method.

a. What is the code of your transfer method?

b. Does your program now run correctly?

c. Which other method(s) should be protected as well?

3. We want to make it impossible to overdraw bank accounts.

a. Why can't we simply make the following check in the TransferRunnable?

if (bank.getBalance(from) >= amount)
   bank.transfer(from, to, amount);

b. Add a condition object to the Bank class:

private Condition sufficientFunds = bankLock.newCondition();

In the transfer method, add a loop

while (accounts[from] < amount)
{
   sufficientFunds.await();
}

c. Run the program. What happens? Why?

d. Add a call

sufficientFunds.signalAll();

at an appropriate place. Where did you add it?

e. How does the program behave now?

f. What happens if you replace the call to signalAll with a call to signal? Why? (If nothing interesting happens, reduce NACCOUNTS to 4.) Make sure to undo these changes before you continue.

4. a. Consider the following deadlock situation:

Account 1: $200

Account 2: $300

Thread 1: Transfer $300 from Account 1 to Account 2

Thread 2: Transfer $400 from Account 2 to Account 1

Why can this not happen in our program?

b. In the run method of the TransferRunnable class, locate the call to transfer and flip fromAccount and toAccount. Set NACCOUNTS to 10.

Run the program. What happens? Why?

c. Undo the flip of the accounts, but construct each transfer runnable with a max value of 2 * INITIAL_BALANCE and run the program. What happens? Why?

TIP: When the program hangs, type CTRL+\. You will get a thread dump that lists all threads. Each thread has a stack trace, telling you where it is currently blocked. Alternatively, run jconsole or jvisualvm and consult the Threads panel.