se.lth.cs.realtime.semaphore
Class MultistepSem

java.lang.Object
  |
  +--se.lth.cs.realtime.semaphore.MultistepSem
All Implemented Interfaces:
Semaphore

public final class MultistepSem
extends java.lang.Object
implements Semaphore

Counting semaphore permitting increments and decrements that are greater than one. Apart from the cases when the ordinary CountingSem can be used, a MultistepSem is useful also in the following two situations:

  1. Multiple resources need to be atomically allocated. For instance, requesting exclusive use of two hardware ports can be accomplished in one operation, but calling taketwice could result in a deadlock.
  2. Several threads that have been blocked by calling take all need to be released by another signaling thread. Not to require that the signaling thread need to know the number of waiting threads, the method simply releases them all.

The order of the awakenings of the threads which called take depends on the underlying OS and/or VM, but for standard implementation in pure Java it will be the same as for the wait/notify mechanism.

See Also:
Semaphore, CountingSem, BinarySem, MutexSem

Constructor Summary
MultistepSem()
          Creates a new MultistepSem with the internal counter initialized to 0.
MultistepSem(int init)
          Creates a new MultistepSem, initializing it to the specified (possibly negative) number.
 
Method Summary
 void give()
          The same as give(1).
 void give(int howMany)
          Increments the internal counter by the supplied number of steps and releases that many blocked thread, if any.
 void giveAll()
          Increments the internal counter by the number of steps needed to release all blocked threads, if any.
 void take()
          The same as take(1).
 void take(int howMany)
          Causes the calling thread to block until the counter represented by this semaphore assumes a value greater than defined by the argument, that is, until that many resources are available.
 boolean tryTake(long timeout)
          Calling tryTake(maxtime)is the same as calling tryTake(maxtime,1).
 boolean tryTake(long timeout, int howMany)
          Try to atomically take one or several resources within a certain time.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

MultistepSem

public MultistepSem()
Creates a new MultistepSem with the internal counter initialized to 0.

MultistepSem

public MultistepSem(int init)
Creates a new MultistepSem, initializing it to the specified (possibly negative) number.
Method Detail

give

public void give(int howMany)
Increments the internal counter by the supplied number of steps and releases that many blocked thread, if any. This is like an atomic multiple give().
Throws:
java.lang.IllegalArgumentException - if the argument is not positive.
See Also:
CountingSem.give()

give

public void give()
The same as give(1).
Specified by:
give in interface Semaphore

giveAll

public void giveAll()
Increments the internal counter by the number of steps needed to release all blocked threads, if any. This is like an atomic multiple give() as many times as the (to the caller unknown) number of threads waiting.

Note that even if all threads are released, a (high priority) thread arriving after giveAll but before the last returning (previously blocked) thread can pass. That is, the thread that has not returned will be blocked again, as one would expect.


take

public void take(int howMany)
Causes the calling thread to block until the counter represented by this semaphore assumes a value greater than defined by the argument, that is, until that many resources are available. Before returning, this number is decremented as many steps as requested.
Throws:
SemInterrupted - (which is an error and not an exception) if the calling thread has been interrupted before or during blocking. You should not catch such an error, except for special cases like handling system shut-down.
java.lang.IllegalArgumentException - if the argument is not positive.

take

public void take()
The same as take(1).
Specified by:
take in interface Semaphore
Following copied from interface: se.lth.cs.realtime.semaphore.Semaphore
Throws:
SemInterrupted - (which is an error and not an exception) if the calling thread has been interrupted before or during blocking. The caller is not expected to catch this type of error, except for properly shut-down of the application, since continued execution most likely will violate resource allocation rules and result in concurrency faults.

tryTake

public boolean tryTake(long timeout,
                       int howMany)
Try to atomically take one or several resources within a certain time. Like the method tryTake as defined in the Semaphore interface, there is a timeout on the take operation, as specified by the first argument. The second argument is for the multi-step feature of this class.
Returns:
true if the semaphore was successfully taken the specified number of steps, and false if the timeout occured which means that the semaphore was not taken at all.
Throws:
SemInterrupted - (which is an error and not an exception) if the calling thread has been interrupted before or during blocking. Usually, you should not catch such an error.
java.lang.IllegalArgumentException - if the second argument is not positive.

tryTake

public boolean tryTake(long timeout)
Calling tryTake(maxtime)is the same as calling tryTake(maxtime,1).
Specified by:
tryTake in interface Semaphore
Following copied from interface: se.lth.cs.realtime.semaphore.Semaphore
Returns:
the success of take, that is, true if the semaphore was taken and false if the return was due to a timeout. Hence, be careful to make use of the returned value not to proceed using a resource without really having reserved it.
Throws:
SemInterrupted - (which is an error and not an exception) if the calling thread has been interrupted before or during blocking. The caller is not expected to catch this type of error, except for properly shut-down of the application, since continued execution most likely will violate resource allocation rules and result in concurrency faults.