-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathArrayBlockingQueue.java
More file actions
108 lines (94 loc) · 2.47 KB
/
ArrayBlockingQueue.java
File metadata and controls
108 lines (94 loc) · 2.47 KB
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package notify;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import static org.apache.curator.shaded.com.google.common.base.Preconditions.checkNotNull;
/**
* @author cry777
* @program demo1
* @description
* @create 2022-01-18
*/
public class ArrayBlockingQueue<E> {
ReentrantLock lock;
Condition notEmpty;
Condition notFull;
Object[] items;
int count;
int putIndex;
/**
* ArrayBlockingQueue构造函数
*
* @param capacity
* @param fair
* @return
*/
public ArrayBlockingQueue(int capacity, boolean fair) {
if (capacity <= 0) {
throw new IllegalArgumentException();
}
this.items = new Object[capacity];
lock = new ReentrantLock(fair);
notEmpty = lock.newCondition();
notFull = lock.newCondition();
}
/**
* 出队
* @param
* @return E
*/
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0) { // 队列为空时, 阻塞当前消费者
notEmpty.await();
}
// 队列没满, 通知生产者生产元素
return dequeue();
} finally {
lock.unlock();
}
}
/**
* 入队
* @param e
* @return void
*/
public void put(E e) throws InterruptedException {
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == items.length) {
notFull.await();
}
// 队列没满, 通知消费者获取元素
enqueue(e);
} finally {
lock.unlock();
}
}
/**
* 通知消费元素
* @param x
* @return void
*/
private void enqueue(E x) {
final Object[] items = this.items;
items[putIndex] = x;
if (++putIndex == items.length) {
putIndex = 0;
}
count++;
notEmpty.signal(); // 队列没满时,通知消费者获取元素
}
/**
* 通知生产元素
* @param x
* @return void
*/
private void dequeue(E x) {
// ...
notEmpty.signal(); // 队列没满时,通知生产者生产元素
}
}