org.clapper.util.misc
Class ObjectLockSemaphore

java.lang.Object
  extended by org.clapper.util.misc.ObjectLockSemaphore
All Implemented Interfaces:
Semaphore

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

public class ObjectLockSemaphore
extends java.lang.Object
implements 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:

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
 }
 

Version:
$Revision: 6735 $
Author:
Copyright © 2004-2007 Brian M. Clapper

Constructor Summary
ObjectLockSemaphore(int initialCount)
          Deprecated. Allocate a new semaphore with the specified initial count.
 
Method Summary
 boolean acquire()
          Deprecated. Acquire this semaphore.
 boolean acquire(long timeout)
          Deprecated. Acquire this semaphore.
 void addToCount(int delta)
          Deprecated. Increment the semaphore's current value, as well as its maximum value.
 int getValue()
          Deprecated. Get the semaphore's current value (i.e., its count).
 void release()
          Deprecated. Release this semaphore, incrementing its counter.
 java.lang.String toString()
          Deprecated. Return a string representation of the semaphore.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

ObjectLockSemaphore

public ObjectLockSemaphore(int initialCount)
Deprecated. 
Allocate a new semaphore with the specified initial count.

Parameters:
initialCount - Initial semaphore count.
Method Detail

acquire

public boolean acquire(long timeout)
                throws SemaphoreException
Deprecated. 
Acquire this semaphore. If the semaphore isn't available, the current thread is put to sleep until either (a) the semaphore is available, or (b) the timeout period expires.

Specified by:
acquire in interface Semaphore
Parameters:
timeout - Timeout period, in milliseconds. A value of 0 means "wait forever, until the semaphore is available." A negative value means "return immediately if the semaphore is not available."
Returns:
true if the semaphore was successfully acquired, false if the timeout expired.
Throws:
SemaphoreException - error attempting to acquire semaphore
See Also:
acquire()

acquire

public boolean acquire()
                throws SemaphoreException
Deprecated. 
Acquire this semaphore. If the semaphore isn't available, this method waits forever for the semaphore to become available. Calling this version of acquire() is exactly equivalent to calling acquire(long) with a timeout value of 0.

Specified by:
acquire in interface Semaphore
Throws:
SemaphoreException - error attempting to acquire semaphore
See Also:
acquire(long)

addToCount

public void addToCount(int delta)
                throws SemaphoreException
Deprecated. 
Increment the semaphore's current value, as well as its maximum value. This method is useful in cases where the semaphore is controlling access to multiple instances of a resource (e.g, database connections, file descriptors, etc.), and more instances of the controlled resource have become available.

Specified by:
addToCount in interface Semaphore
Parameters:
delta - The amount by which to increment the count.
Throws:
SemaphoreException - error updating semaphore's count

getValue

public int getValue()
             throws SemaphoreException
Deprecated. 
Get the semaphore's current value (i.e., its count).

Specified by:
getValue in interface Semaphore
Returns:
the current value of the semaphore
Throws:
SemaphoreException - error getting semaphore's value

release

public void release()
             throws SemaphoreException
Deprecated. 
Release this semaphore, incrementing its counter.

Specified by:
release in interface Semaphore
Throws:
SemaphoreException - error getting semaphore's value

toString

public java.lang.String toString()
Deprecated. 
Return a string representation of the semaphore.

Overrides:
toString in class java.lang.Object
Returns:
A printable representation of the semaphore.


Copyright © 2004-2007 Brian M. Clapper. All Rights Reserved.