-
Notifications
You must be signed in to change notification settings - Fork 7
/
MySemaphore.java
48 lines (41 loc) · 1.64 KB
/
MySemaphore.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
// A standard exercise of Concurrency Intro is to prove that Semaphores are
// equivalent to Locks and Condition variables in power, shown by implementing
// each one with the other. Here, a simple Semaphore implementation.
public class MySemaphore {
private int permits;
private final Lock mutex;
private final Condition permitAvailable;
public MySemaphore(int permits, boolean fair) {
this.permits = permits;
this.mutex = new ReentrantLock(fair);
this.permitAvailable = mutex.newCondition();
}
public void acquire() throws InterruptedException {
mutex.lock();
try {
while(permits < 1) {
// Wait for one permit to become available.
permitAvailable.await();
}
permits--;
}
// Ensure that mutex is unlocked even if an exception is thrown.
finally { mutex.unlock(); }
}
public void release() {
mutex.lock();
permits++;
// One waiting thread can now acquire a permit.
if(permits > 0) { permitAvailable.signal(); }
mutex.unlock();
}
}
// Puzzle: assuming that the Lock mutex is FIFO, is this Semaphore also FIFO in that
// the threads that call acquire are always guaranteed to get the permit in the order
// in which they made these calls?
// Another puzzle: what would happen if you commented out the mutex operations from
// the release method? Devise a scenario where the semaphore would no longer work
// correctly.