Java Reference
In-Depth Information
How It Works
We now allocate arrays for the initial account balances, the totals of credits and debits for each account, and
the totals for the accounts themselves. The number of initializing values in the
initialBalance[]
array
will determine the number of elements in each of the arrays. In the
for
loop, we create each of the accounts
with the appropriate initial balance, and initialize the
totalCredits[]
and
totalDebits[]
arrays to zero.
In the modified transactions loop, we select the account from the array for both the debit and the credit
transactions by generating a random index value that we store in the variable
select
. The index
select
is also used to keep a tally of the total of the transactions of each type.
This is all well and good, but by declaring the methods in the class
Bank
as
synchronized
, we're
limiting the program quite significantly. No operation of any kind can be carried out while any other
operation is in progress. This is unnecessarily restrictive since there's no reason to prevent a transaction
on one account while a transaction for a different account is in progress. What we really want to do is
constrain the program to prevent overlapping of operations on the same account, and this is where
declaring blocks of code to be synchronized on a particular object can help.
Let's consider the methods in the class
Bank
once more. What we really want is the code in the
doTransaction()
method to be synchronized so that simultaneous processing of the same account is
prevented, not so that processing of different accounts is inhibited. What we need to do is synchronize
the processing code for a transaction on the
Account
object that is involved.
Try It Out - Applying synchronized Statement Blocks
We can do this with the following changes:
class Bank {
// Perform a transaction
public void doTransaction(Transaction transaction) {
switch(transaction.getTransactionType()) {
case Transaction.CREDIT:
synchronized(transaction.getAccount()) {
// Get current balance
int balance = transaction.getAccount().getBalance();
// Credits require require a lot of checks...
try {
Thread.sleep(100);
} catch(InterruptedException e) {
System.out.println(e);
}
balance += transaction.getAmount(); // Increment the balance
transaction.getAccount().setBalance(balance); // Restore account balance
break;
}
case Transaction.DEBIT:
synchronized(transaction.getAccount()) {
// Get current balance
int balance = transaction.getAccount().getBalance();