- acquire
- release
Real time examples:
- Semaphores can be used to restrict number of database connections at a time
- Semaphores can also be used to bound any collection.
Example:
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
49
50
51
52
53
54
55
56
57
58
59
|
package org.arpit.java2blog.bean;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Semaphore;
public class BoundedArrayList {
private final Semaphore semaphore;
private List arraylist;
BoundedArrayList(int limit) {
this.arraylist = Collections.synchronizedList(new ArrayList());
semaphore = new Semaphore(limit);
}
/*
* Add element to the list and call semaphore.acquire method
* */
public boolean add(T t) throws InterruptedException {
boolean added = false;
semaphore.acquire();
try {
added = arraylist.add(t);
return added;
} finally {
if (!added)
semaphore.release();
}
}
/*
* remove element from the list and call semaphore.release method
* */
public boolean remove(T t) {
boolean wasRemoved = arraylist.remove(t);
if (wasRemoved)
semaphore.release();
return wasRemoved;
}
public void remove(int index) {
arraylist.remove(index);
semaphore.release();
}
public List getArraylist() {
return arraylist;
}
public Semaphore getSemaphore() {
return semaphore;
}
}
|
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
|
package org.arpit.java2blog.bean;
public class BoundedArrayListMain {
public static void main(String[] args) throws InterruptedException {
final BoundedArrayList ba = new BoundedArrayList(5);
Runnable runnable1 = new Runnable() {
@Override
public void run() {
try {
ba.add("John");
ba.add("Martin");
ba.add("Adam");
ba.add("Prince");
ba.add("Tod");
System.out.println("Available Permits : "+ba.getSemaphore().availablePermits());
ba.add("Tony");
System.out.println("Final list: "+ba.getArraylist());
} catch (InterruptedException ie) {
}
}
};
Runnable runnable2 = new Runnable() {
@Override
public void run() {
try {
System.out.println("Before removing elements: "+ ba.getArraylist());
Thread.sleep(5000);
ba.remove("Martin");
ba.remove("Adam");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t1 = new Thread(runnable1);
Thread t2 = new Thread(runnable2);
t1.start();
t2.start();
}
}
|
1
2
3
4
5
|
Available Permits : 0
Before removing elements: [John, Martin, Adam, Prince, Tod]
Final list: [John, Prince, Tod, Tony]
|
Explanation:
- We have created two thread t1 and t2.
- t1 and t2 both share common list reference ba.
- When t1 adds 5 elements to the list, available permits became 0.
- Now t1 waits for another thread to remove elements, so that semaphore have some available permits.
- Another thread t2 removes elements from the list after waiting for 5 secs.
- Once t2 removes elements, t1 adds “Tony” to list.