|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
Common methods of all types of semaphores, which implements the well-known basic primitive for synchronization and mutual exclusion within the field of concurrent and real-time programming. Basically, a semaphore is an integer-valued variable which can be atomically accessed by only one thread at a time.
Accesses are either of the take
type to be used
for taking (locking, requesting to continue execution using it,
etc.) a resource, or of the give
type providing
access to the resource (or piece of code) for other threads. These
methods, take
and give
, are defined to have
no arguments here, implicitly assuming increments/decrements of
one. In addition, classes implementing this interface may define
additionally overloaded methods, for other increments or other
specific features. Furthermore, the semantics of the take
and give
with no arguments can differ in different classes.
Note, there is no method defined in this interface for getting the
value of the internal counter, and no such method is expected to be
provided in any implementing class. That would result in misuse of
semaphores, in particular among beginners in concurrent
programming. However, a method tryTake
has been added
to permit a thread to check if a resource could be taken within a
certain time, and if so, the semaphore is actually taken. This
method has been given a different name (instead of simply
overloading take) to point out the different behavior, avoiding
programming errors resulting in threads that proceed after a timeout
as if the resource had been allocated.
take
and give
are normally not
declared synchronized in implementing classes for the following two
reasons: Object
) on the semaphore object itself, there is
nothing in Java preventing any thread with a reference to the
semaphore to call wait and notify directly in a synchronized block,
thereby interfering with the intended behavior of the semaphore
methods and probably causing the application to behave
erroneously. Instead, blocking/locking is accomplished using a
private lock object. It is up to native implementations to
accomplish the same thing in more efficient ways.
give
and
take
can be the most appropriate/efficient way of
preventing a context switch over the small number of native
instructions. Even if a compiler (to native code) is free to
accomplish mutual exclusion for small synchronized
methods by disabling interrupts, this is from a programming and
portability point of view different from explicitly disabling
interrupts. A semaphore class for embedded systems, however, is
often optimized with respect to the particular platform (OS and HW)
and should be considered as a built-in mechanism independently of
wait and notify (which may not even be supported natively), and
hence the methods (although atomic) should not be viewed as
synchronized
.
Another reason for disabling interrupts, mainly for natively
compiled applications or special VMs, is to permit
give
to be called from an interrupt routine (which may
not be blocked even temporarily).
Threads calling the blocking methods (take
and
tryTake
) are to be thrown an error if they are
interrupted, as described in the documentation of those methods. As
usual, errors (which implements throwable) can be caught, but in
normal cases the user program is not expected to catch them.
CountingSem
,
MutexSem
,
MultistepSem
,
BinarySem
Method Summary | |
void |
give()
Increments by 1 the counter represented by this semaphore, and notify at least one, if any, of the waiting threads. |
void |
take()
Causes the calling thread to block until the counter that represents this semaphore obtains a positive value. |
boolean |
tryTake(long timeout)
Causes the calling thread to block until the counter that represents this semaphore obtains a positive value (just like the ordinary take method) or until the timeout
time has passed. |
Method Detail |
public void give()
   ++count;
   notify();
public void take()
count
below, is decremented by 1.
Basically this means executing   while (count<1) wait();
   --count;
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.public boolean tryTake(long timeout)
timeout
time has passed.
If, due to other threads calling give, the semaphore is
possible to take, but the caller of take
is not
rescheduled for execution until after the timeout
time after its call of take, it is considered as a timeout and
hence false
is returned (and the internal state of
the semaphore is left unchanged).
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.
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |