The JavaTM Tutorial
Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Trail: Essential Java Classes
Lesson: Threads: Doing Two or More Tasks At Once

Locking an Object

Within a program, the code segments that access the same object from separate, concurrent threads are called critical sections. A critical section can be a block or a method and is identified with the synchronized keyword. The Java platform associates a lock with every object and the lock is acquired upon entering a critical section.

In the producer-consumer example, the put and get methods of CubbyHole.java are the critical sections. The Consumer should not access the CubbyHole when the Producer is changing it, and the Producer should not modify it when the Consumer is getting the value. So put and get in the CubbyHole class should be marked with the synchronized keyword.

Here’s a code skeleton for the CubbyHole class:

public class CubbyHole {
    private int contents;
    private boolean available = false;

    public synchronized int get(int who) {
        ...
    }

    public synchronized void put(int who, int value) {
        ...
    }
}
The method declarations for both put and get contain the synchronized keyword. Whenever control enters a synchronized method, the thread that called the method locks the object whose method has been called. Other threads cannot call a synchronized method on the same object until the object is unlocked.

Thus, when it calls CubbyHole's put method, The Producer locks the CubbyHole, thereby preventing the Consumer from calling the CubbyHole's get method:

public synchronized void put(int value) {
    //CubbyHole locked by the Producer
    ...
    //CubbyHole unlocked by the Producer
}
When the put method returns, the Producer unlocks the CubbyHole.

Similarly, when the Consumer calls CubbyHole's get method, it locks the CubbyHole, thereby preventing the Producer from calling put:

public synchronized int get() {
    // CubbyHole locked by the Consumer
    ...
    // CubbyHole unlocked by the Consumer
}
The acquisition and release of a lock is done automatically and atomically by the Java run-time system. This ensures that race conditions cannot occur in the underlying implementation of the threads, thus ensuring data integrity.

Synchronization isn't the whole story. The two threads must also be able to notify one another when they've done their job. Learn more about that after a brief foray into reentrant locks.


Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Copyright 1995-2005 Sun Microsystems, Inc. All rights reserved.