The following code snippet is a solution to https://leetcode.com/problems/print-in-order/ which runs printFirst.run(), printSecond.run(), and printThird.run() in order using a single semaphore. Three threads A, B, and C call the functions. Thread A will call first, thread B will call second, and thread C will call third.
I understand why lock.acquire(); followed by lock.release(); is required in third, rather than calling lock.acquire(2); immediately, due to the way Java assigns permits to waiting threads in a queue. Calling lock.acquire(2); creates a deadlock as nothing can ever release enough permits.
That being said, I do not understand how lock.acquire(); followed by lock.release(); before this fixes it.
Would somebody be able to explain to me what happens in the situation where first first calls lock.release() and then third calls lock.acquire(); lock.release(); lock.acquire(2); before second runs? Does this result in a deadlock, in the same way that calling lock.acquire(2); by itself would result in a deadlock? Is this just an unlikely situation which is why this works?
Any help with this would be greatly appreciated, thank you!
class Foo {
private Semaphore lock = new Semaphore(0);
public void first(Runnable printFirst) throws InterruptedException {
// printFirst.run() outputs "first". Do not change or remove this line.
printFirst.run();
lock.release();
}
public void second(Runnable printSecond) throws InterruptedException {
lock.acquire();
// printSecond.run() outputs "second". Do not change or remove this line.
printSecond.run();
lock.release(2);
}
public void third(Runnable printThird) throws InterruptedException {
lock.acquire();
lock.release();
lock.acquire(2);
// printThird.run() outputs "third". Do not change or remove this line.
printThird.run();
}
}