Leslie
Leslie

Reputation: 353

Do Semaphores block the calling thread or does the thread block itself?

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

Answers (1)

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();
}

What does "blocking" mean?

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

Related Questions