Threads may be seen as methods that execute at "the same time" as other methods. Normally, we think sequentially when writing a computer program. From this perspective, only one thing executes at a time. However, with today's multi-core processors, it is possible to literally have several things going on at the very same time while sharing the same memory. There are lots of ways that this is done in the real world, and this chapter goes over them in a way that you can apply to your own projects.
14.6 CASE STUDY: Cooperating Threads
Java Monitors and Mutual Exclusion
An object that contains synchronized methods has a monitor associated
with it. A monitor is a widely used synchronization mechanism that ensures that only one thread at a time can execute a synchronized method.
When a synchronized method is called, a lock is acquired on that object.
For example, if one of the Customer threads calls nextNumber(), a lock
will be placed on that TakeANumber object. While an object is locked, no
other synchronized method can run in that object. Other threads must
wait for the lock to be released before they can execute a synchronized
method.
While one Customer is executing nextNumber(), all other Customers will be forced to wait until the first Customer is finished. When the synchronized method is exited, the lock on the object is released, allowing other Customer threads to access their synchronized methods. In effect, a synchronized method can be used to guarantee mutually exclusive access to the TakeANumber object among the competing
customers.
One cautionary note here is that although a synchronized method blocks
access to other synchronized methods, it does not block access to non-synchronized methods. This could cause problems. We will return to this
issue in the next part of our case study when we discuss the testing of our
program.