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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
| import java.util.concurrent.atomic.AtomicStampedReference;
public class Queue<T> {
final Node<T> sentinel = new Node<>();
final AtomicStampedReference<Node<T>> Head;
final AtomicStampedReference<Node<T>> Tail;
Queue() {
Head = new AtomicStampedReference<>(sentinel, 0);
Tail = new AtomicStampedReference<>(sentinel, 0);
}
void enqueue(T value) {
Node<T> node = new Node<>(value);
AtomicStampedReference<Node<T>> tail = new AtomicStampedReference<>(null, 0);
AtomicStampedReference<Node<T>> next;
while (true) {
tail.set(Tail.getReference(), Tail.getStamp());
next = tail.getReference().next;
if (tail.getReference() == Tail.getReference()) {
if (next.getReference() == null) {
if (next.compareAndSet(null,
node,
next.getStamp(),
next.getStamp() + 1)) {
break;
}
} else {
Tail.compareAndSet(tail.getReference(),
next.getReference(),
tail.getStamp(),
tail.getStamp() + 1);
}
}
}
Tail.compareAndSet(tail.getReference(), node, tail.getStamp(), tail.getStamp() + 1);
}
boolean dequeue() {
AtomicStampedReference<Node<T>> head = new AtomicStampedReference<>(null, -1);
AtomicStampedReference<Node<T>> tail = new AtomicStampedReference<>(null, -1);
AtomicStampedReference<Node<T>> next;
while (true) {
head.set(Head.getReference(), Head.getStamp());
tail.set(Tail.getReference(), Tail.getStamp());
next = head.getReference().next;
if (head.getReference() == Head.getReference()) {
if (head.getReference() == tail.getReference()) {
if (next.getReference() == null) {
return false;
}
Tail.compareAndSet(tail.getReference(), next.getReference(), tail.getStamp()
, tail.getStamp() + 1);
} else {
if (Head.compareAndSet(head.getReference(),
next.getReference(),
head.getStamp(),
head.getStamp() + 1)) {
break;
}
}
}
}
return true;
}
boolean dequeue(T[] temp) {
AtomicStampedReference<Node<T>> head = new AtomicStampedReference<>(null, -1);
AtomicStampedReference<Node<T>> tail = new AtomicStampedReference<>(null, -1);
AtomicStampedReference<Node<T>> next;
while (true) {
head.set(Head.getReference(), Head.getStamp());
tail.set(Tail.getReference(), Tail.getStamp());
next = head.getReference().next;
if (head.getReference() == Head.getReference()) {
if (head.getReference() == tail.getReference()) {
if (next.getReference() == null) {
return false;
}
Tail.compareAndSet(tail.getReference(), next.getReference(), tail.getStamp()
, tail.getStamp() + 1);
} else {
temp[0] = next.getReference().value;
if (Head.compareAndSet(head.getReference(),
next.getReference(),
head.getStamp(),
head.getStamp() + 1)) {
break;
}
}
}
}
return true;
}
void goThrough() {
AtomicStampedReference<Node<T>> iter = Head.getReference().next;
while (iter.getReference() != null) {
System.out.println(iter.getReference().value);
iter = iter.getReference().next;
}
}
}
class Node<T> {
T value;
final AtomicStampedReference<Node<T>> next = new AtomicStampedReference<>(null, 0);
Node() {
}
Node(T value) {
this.value = value;
}
}
|