-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathArrayQueue.java
More file actions
73 lines (66 loc) · 1.67 KB
/
ArrayQueue.java
File metadata and controls
73 lines (66 loc) · 1.67 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
import java.nio.*;
import java.util.concurrent.locks.*;
// Array queue is a bounded lock-based FIFO queue using
// an array. It uses 2 separate locks for head and tail.
class ArrayQueue<T> {
Lock headLock;
Lock tailLock;
T[] data;
int head;
int tail;
// headLock: lock for enq() at head
// tailLock: lock for deq() at tail
// data: array of values in stack
// head: front of queue (0)
// tail: rear of queue (0)
@SuppressWarnings("unchecked")
public ArrayQueue(int capacity) {
headLock = new ReentrantLock();
tailLock = new ReentrantLock();
data = (T[]) new Object[capacity+1];
head = 0;
tail = 0;
}
// 1. Lock tail.
// 2. Try enq.
// 3. Unlock tail.
public void enq(T x) {
try {
tailLock.lock(); // 1
tryEnq(x); // 2
} finally {
tailLock.unlock(); // 3
}
}
// 1. Lock head.
// 2. Try deq.
// 3. Unlock head.
public T deq() {
try {
headLock.lock(); // 1
return tryDeq(); // 2
} finally {
headLock.unlock(); // 3
}
}
// 1. Ensure queue is not full
// 2. Save data at tail.
// 3. Increment tail.
protected void tryEnq(T x) {
int tail2 = (tail + 1) % data.length; // 1, 3
if (tail2 == head) // 1
throw new BufferOverflowException(); // 1
data[tail] = x; // 2
tail = tail2; // 3
}
// 1. Ensure queue is not empty.
// 2. Return data at head.
// 3. Increment head.
protected T tryDeq() {
if (head == tail) // 1
throw new BufferUnderflowException(); // 1
T x = data[head]; // 2
head = (head + 1) % data.length; // 3
return x; // 2
}
}