4.2 Mutual Exclusion in Java


4.2 Mutual Exclusion in Java

Concurrent activations of a method in Java can be made mutually exclusive by prefixing the method with the keyword synchronized.

The Counter class from the Ornamental Garden program can be corrected by deriving a SynchronizedCounter class from Counter and making the increment method in the subclass synchronized as shown in Program 4.3.

Program 4.3: Corrected Counter class.

image from book
 class SynchronizedCounter extends Counter {   SynchronizedCounter(NumberCanvas n)      {super(n);}   synchronized void increment() {        super.increment();   } }
image from book

Java associates a lock with every object. The Java compiler inserts code to acquire the lock before executing the body of a synchronized method and code to release the lock before the method returns. Concurrent threads are blocked until the lock is released. Since only one thread at a time may hold the lock, only one thread may be executing the synchronized method. If this is the only method, as in the example, mutual exclusion to the shared object is ensured. If an object has more than one method, to ensure mutually exclusive access to the state of the object, all the methods should be synchronized.

Access to an object may also be made mutually exclusive by using the synchronized statement:

 synchronized (object) { statements }

This acquires the referenced object’s lock before executing the bracketed statement block and releases it on exiting the block. For example, an alternative (but less elegant) way to correct the example would be to modify the Turnstile.run() method to use:

 synchronized(people) {people.increment();}

This is less elegant as the user of the shared object has the responsibility for imposing the lock, rather than embedding it in the shared object itself. Since not all users of the object may act responsibly, it may also be less secure against interference.

The output from the corrected Ornamental Garden program is depicted in Figure 4.7. The only change is to use the class defined in Program 4.3 rather than the original Counter class. This change is made by clicking the Fix It check box before pressing Go.

image from book
Figure 4.7: Corrected Garden display.

Once a thread has acquired the lock on an object by executing a synchronized method, that method may itself call another synchronized method from the same object (directly or indirectly) without having to wait to acquire the lock again. The lock counts how many times it has been acquired by the same thread and does not allow another thread to access the object until there has been an equivalent number of releases. This locking strategy is sometimes termed recursive locking since it permits recursive synchronized methods. For example:

 public synchronized void increment(int n) {    if (n>0) {        ++value;        increment(n-1);    } else return; }

This is a rather unlikely recursive version of a method which increments value by n. If locking in Java was not recursive, it would cause a calling thread to be blocked forever, waiting to acquire a lock which it already holds!




Concurrency(c) State Models & Java Programs
Concurrency: State Models and Java Programs
ISBN: 0470093552
EAN: 2147483647
Year: 2004
Pages: 162

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net