Java Reference
In-Depth Information
amount = 30 + rand.nextInt(31); // Generate amount of $30 to $60
transaction = new Transaction(accounts[select], // Account
Transaction.DEBIT, // Debit transaction
amount); // of amount
totalDebits[select] += amount; // Keep total debit tally
clerk2.doTransaction(transaction); // Now do the debit
}
We have just deleted the loop blocks that were waiting until a clerk became free. This makes our code a
lot shorter.
With a small change to the
isBusy()
method in the
Clerk
class, we can also eliminate the need for
the
while
loop before we output the results in
main()
:
synchronized public void isBusy() {
while(inTray != null) { // Is this object busy?
try {
wait(); // Yes, so wait for notify call
} catch(InterruptedException e) {
System.out.println(e);
}
return; // It is free now
}
}
Now the
isBusy()
method will only return when the clerk object has no transaction waiting or in
progress, so no return value is necessary. The
while
loop in
main()
before the final output statements
can be replaced by:
// Wait until both clerks are done
clerk1.isBusy();
clerk2.isBusy();
How It Works
The
doTransaction()
method for a
Clerk
object calls the
wait()
method if the
inTray
field
contains a reference to a transaction object, as this means the
Clerk
object is still processing a credit or
a debit. This will result in the current thread (which is the main thread) being suspended until the
notifyAll()
method is called by this object's
run()
method to indicate a change to the clerk.
Because the
run()
method is also synchronized on the
Clerk
object, it too can call
wait()
in this case, if
the
inTray
contains
null
, since this indicates that there is no transaction waiting for the clerk to expedite.
A call to the
doTransaction()
method for the
Clerk
object will result in a transaction being stored in
inTray
, and the
notifyAll()
call will wake up the
run()
method to continue execution.
Because we've declared the
isBusy()
method as
synchronized
, we can call the
wait()
method to
suspend the current thread if transactions are still being processed. Since we don't return from the
method until the outstanding transaction is complete, we have no need of a
boolean
return value.