Documentation API of the 'org.clapper.util.misc.ObjectLockSemaphore' Java class
ObjectLockSemaphore
org.clapper.util.misc

Class ObjectLockSemaphore

  • All Implemented Interfaces:
    Semaphore

    Deprecated. 
    J2SE 5.0 now provides a java.util.concurrent.Semaphore class

    public class ObjectLockSemaphoreextends Objectimplements Semaphore

    NOTE: This class, and its parent interface, are deprecated. With J2SE 5.0 (a.k.a., Java 1.5), the JDK provides its own semaphore class, java.util.concurrent.Semaphore.

    The ObjectLockSemaphore class implements the Semaphore interface and provides a classic counting semaphore that uses the Java object-locking primitives (the same locking primitives used to implement synchronized critical sections) to ensure that ObjectLockSemaphore objects are atomically created, accessed, updated and destroyed.

    Warning: Do not attempt to acquire or release a semaphore within a critical region--that is, within a "synchronized" section--or you'll risk deadlock. The Semaphore class is implemented using the Java VM's object monitor capability, the same capability that controls how synchronized sections work. The following code fragment is likely to cause a deadlock:

     private ArrayList bufferPool = ...; private Semaphore sem = new ObjectLockSemaphore (bufferPool.size()); public MyBuffer getBuffer() {     MyBuffer result = null;     synchronized (bufferPool)     {                                       // bufferPool is now locked         sem.acquire();                // bufferPool is still locked         result = (MyBuffer) bufferPool.removeElementAt (0);     }     return result; } public void returnBuffer (MyBuffer buf) {     synchronized (bufferPool)     {                                       // bufferPool is now locked         bufferPool.addElement (buf);     }     sem.release();                    // bufferPool is still locked } 

    Given the above code, assume:

    • The semaphore is initialized to the number of buffers in the pool.
    • All buffers are unavailable (i.e., have been handed out).
    • Thread A wants a buffer.
    • Thread B is using one, but is almost finished with it.

    Here's how the deadlock can occur:

    1. Thread A calls the getBuffer() method.
    2. Thread A enters the synchronized (bufferPool) block in getBuffer. As a result, Thread A acquires the Java monitor for the bufferPool object. Recall that only one thread can hold a given object's monitor at a time.
    3. Thread A calls sem.acquire(). Since there are no buffers available, the semaphore's value is 0, so Thread A goes to sleep while it is still holding the monitor lock on the bufferPool object.
    4. Thread B finishes with its buffer. It calls the returnBuffer() method.
    5. Within returnBuffer(), Thread B attempts to acquire the monitor lock for the bufferPool object--but Thread A is already holding that lock, so Thread B goes to sleep, waiting for Thread A to release the lock.
    6. Deadlock. Thread A is waiting for Thread B to release the semaphore. Thread B, in turn, is waiting for Thread A to release the lock on the bufferPool object.

    This particular deadlock situation is easily avoided as shown:

     private ArrayList bufferPool = ...; private Semaphore sem = new ObjectLockSemaphore (bufferPool.size()); public MyBuffer getBuffer() {     MyBuffer result = null;     sem.acquire();     synchronized (bufferPool)     {         result = (MyBuffer) bufferPool.removeElementAt (0);     }     return result; } public void returnBuffer (MyBuffer buf) {     synchronized (bufferPool)     {                                       // bufferPool is now locked         bufferPool.addElement (buf);     }     sem.release();                    // bufferPool is still locked } 

Warning: You cannot see the full API documentation of this class since the access to the DatMelt documentation for third-party Java classes is denied. Guests can only view jhplot Java API. To view the complete description of this class and its methods, please request the full DataMelt membership.

If you are already a full member, please login to the DataMelt member area before visiting this documentation.