Question 1:
I was reading into Hard-core Multi-threading in Java and did bump up into the semaphore example below.
package com.dswgroup.conferences.borcon.threading;
public class ResourceGovernor {
private int count;
private int max;
public ResourceGovernor(int max) {
count = 0;
this.max = max;
}
public synchronized void getResource(int numberof) {
while (true) {
if ((count + numberof) <= max) {
count += numberof;
break;
}
try {
wait();
} catch (Exception ignored) {}
}
}
public synchronized void freeResource(int numberof) {
count -= numberof;
notifyAll();
}
}
I feel this can lead to deadlock in the below scenario :
All resources are being used and a new thread asks for resources that are not available. Since it waits inside the synchronized function, the other threads that are using the resources are not able to free the resources as the freeResource function is also synchronized and that they can't enter the function as the waiting thread has taken the object level lock of ResourceGovernor
There is another issue that one has not validated if a thread is trying to release more no. of resources than it acquired. But this issue is secondary and can be easily fixed by having the synchronized map of thread name and resource count.
But can i safely say that i diagnosed the 1st problem correctly. (Need to doublecheck since its published for a long time on embarcadero.com)
Question 2:
Can i safely say that a semaphore with only 1 resource has the same behaviour as a mutex lock?
All resources are being used and a new thread asks for resources that are not available. Since it waits inside the synchronized function, the other threads that are using the resources are not able to free the resources as the freeResource function is also synchronized and that they can't enter the function as the waiting thread has taken the object level lock of ResourceGovernor
You've missed the fact that calling wait()
relinquishes the monitor, so other synchronized code is able to execute. From the docs for wait()
:
The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the
notify
method or thenotifyAll
method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
For your second question:
Can I safely say that a semaphore with only 1 resource has the same behaviour as a mutex lock?
I suspect so, although the implementation you've shown doesn't actually stop you from calling freeResource
several times. It's a slightly odd implementation in that I normally see semaphores counting the number of resources remaining rather than the number of resources taken - although they're equivalent, of course.
See more on this question at Stackoverflow