aspose file tools*
The moose likes Java in General and the fly likes Thinking in Java's Concurrency chapter: the BankTellerSimulation example Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Thinking in Java Watch "Thinking in Java New topic

Thinking in Java's Concurrency chapter: the BankTellerSimulation example

Jan Van den bosch

Joined: Apr 17, 2008
Posts: 16

Below is an example in Bruce Eckel's book Thinking in Java. Don't let the number of lines scare you away, it's actually pretty straightforward. For improved readability, you can just paste it in your IDE if you want to, it's a single file with no dependencies. I've added a few comments here and there for my (and your) convenience.

What the program does is simulate a line of customers queueing in front of a number of teller machines. Each customer is served by a teller for a certain amount of time. Additional customers get in line while the programming is running, and the number of active tellers adjusts itself to the total number of customers (in the TellerManager class).

The compareTo() method in Teller is used by the PriorityQueue in TellerManager and is used for sorting the Tellers in said queue, for example upon calling workingTellers.add(teller). These add methods are called in TellerManager.adjustTellerNumber(), which effectively runs in a dedicated TellerManager thread. You can see that in TellerManager's run() method.

Now, Bruce Eckel has synchronized the Teller.compareTo() method. Since Teller.customersServed is shared between the Teller's thread (look at its run() method) and the TellerManager's thread (which calls workingTellers.add(teller), which calls Teller.compareTo(Teller)), I can see why synchronization is necessary.

The part I'm having a problem with is the implementation of compareTo() on line 106. It makes use of other.customersServed. When TellerManager takes the lock on this, it makes sure that this.customersServed cannot be changed while the lock is held, but in the meanwhile, other.customersServed can still be changed by an other thread, since this thread isn't locking on other. What do you think, am I right?

I'd solve the problem with a private synchronized getCustomersServed() method in Teller, and call this method instead of accessing the field directly.

Nitesh Kant

Joined: Feb 25, 2007
Posts: 1638

Moving it to Threads & Synchronization as it is specific to synchronization.

apigee, a better way to API!
subject: Thinking in Java's Concurrency chapter: the BankTellerSimulation example