Reputation: 353
I am currently learning about Semaphores.
I know they are there to restrict access to ressources in a concurrent system.
f.e. in Java a Semaphore class has the methods aquire()
and release()
which calling processes will access.
Now in general, when a Semaphore has four spaces open and four threads try to aquire access, the access will be granted.
But if a fifth thread tries to access the resource the thread has to be blocked or set to sleep somehow. Do I as a programmer have to implement something like
if (semaphore.hasSpaceleft()){
semaphore.aquire();
ressource.access();
} else {
sleep until semaphore.hasSpaceLeft();
}
Or will the semaphore handle sleeping/blocking the calling thread? (not only in Java but in general)
Upvotes: 1
Views: 2396
Reputation: 19236
No, according to docs:
public void acquire() throws InterruptedException
Acquires a permit from this semaphore, blocking until one is available, or the thread is interrupted.
Emphasis mine
Actually, your proposed program has a bug - a race condition - in it:
if (semaphore.hasSpaceleft()){ // 1
semaphore.aquire(); // 2
ressource.access();
} else {
sleep until semaphore.hasSpaceLeft();
}
In the time window between 1
and 2
another thread might acquire the semaphore. That's why in general any semaphore implementation has to be designed around blocking acquire function. Alternatively, you can use tryAcquire()
function:
if (semaphore.tryAcquire()) {
resource.access();
} else {
doSomethingElseInTheMeantime();
}
In general, operating system (OS) is responsible for scheduling threads. If a thread cannot acquire a semaphore, it is suspended by OS (i.e. it is marked as not eligible for running, so that OS scheduler ignores it when selecting threads to run) until semaphore can be acquired again.
Upvotes: 3