I am writing a program to do a gate count of 5, and then allow people into the building (by doing a System.out.println).
I have the following solution, using synchronized. However, someone mentioned this solution does not allow for sequential lock fairness, for people in line. How can I rewrite this to allow for it? Is semaphores below correct?
Using Synchronized:
public class LineCount {
int totalInLine = 0;
public synchronized void addToLine() {
totalInLine = totalInLine + 1;
if (totalInLine == 5) {
System.out.println("People may enter");
totalInLine = 0;
}
}
Using Semaphore:
public class LineCount {
Semaphore semaphore = new Semaphore(5, true);
public void addToLine() throws InterruptedException {
semaphore.acquire();
if (semaphore.availablePermits() == 0) {
System.out.println("People may enter");
semaphore.release(5);
semaphore = new Semaphore(5, true);
}
}
}
The
Semaphore
version is almost, but not quite the same as thesynchronized
version. But, theSemaphore
version isn't thread safe. I suggest two changes:The reason is, if some thread A executes the
semaphore.release(5)
statement, then thread B could slip in, and decrement the old Semaphore before thread A'ssemaphore = new Semaphore(...)
assignment takes effect. That would allow more than five calls before the next time the message is printed.There is no need to create a new Semaphore because each
release(5)
call will allow five more calls to acquire a permit.The reason for
final
is mostly just to make sure that everybody who reads the code will immediately understand thatsemaphore
always will refer to the same object.Update:
I can't even guess what that means. You should ask "someone" for clarity.
Your
synchronized
version ofaddToLine
prints a message on every fifth call. It doesn't do anything else. It doesn't make any caller wait for any longer than it takes some other caller to print the message. Where is the "unfairness" in that?The title of your question is "Program to allow people through a gate." But there's nothing here that really models a gate. There's nothing in it that makes any "person" wait for the "gate" to "open." It's literally just a thread-safe method that prints a certain message on every fifth call.