Skip to content

Commit 44509e5

Browse files
author
zhangquanli
committed
程序清单 12-1 基于信号量的有界缓存
1 parent e0db97a commit 44509e5

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package chapter_12.code_01;
2+
3+
import net.jcip.annotations.GuardedBy;
4+
import net.jcip.annotations.ThreadSafe;
5+
6+
import java.util.concurrent.Semaphore;
7+
8+
/**
9+
* 程序清单 12-1 基于信号量的有界缓存
10+
*/
11+
@ThreadSafe
12+
public class SemaphoreBoundedBuffer<E> {
13+
private final Semaphore availableItems, availableSpaces;
14+
@GuardedBy("this")
15+
private final E[] items;
16+
@GuardedBy("this")
17+
private int putPosition = 0, takePosition = 0;
18+
19+
public SemaphoreBoundedBuffer(int capacity) {
20+
if (capacity <= 0) {
21+
throw new IllegalArgumentException();
22+
}
23+
availableItems = new Semaphore(0);
24+
availableSpaces = new Semaphore(capacity);
25+
items = (E[]) new Object[capacity];
26+
}
27+
28+
public boolean isEmpty() {
29+
return availableItems.availablePermits() == 0;
30+
}
31+
32+
public boolean isFull() {
33+
return availableSpaces.availablePermits() == 0;
34+
}
35+
36+
public void put(E x) throws InterruptedException {
37+
availableSpaces.acquire();
38+
doInert(x);
39+
availableItems.release();
40+
}
41+
42+
public E take() throws InterruptedException {
43+
availableItems.acquire();
44+
E item = doExtract();
45+
availableSpaces.release();
46+
return item;
47+
}
48+
49+
private synchronized void doInert(E x) {
50+
int i = putPosition;
51+
items[i] = x;
52+
putPosition = (++i == items.length) ? 0 : i;
53+
}
54+
55+
private synchronized E doExtract() {
56+
int i = takePosition;
57+
E x = items[i];
58+
items[i] = null;
59+
takePosition = (++i == items.length) ? 0 : i;
60+
return x;
61+
}
62+
}

0 commit comments

Comments
 (0)