2011-09-30 00:26:50 +00:00
|
|
|
package java.util.concurrent;
|
|
|
|
|
2014-03-03 23:02:12 +00:00
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.NoSuchElementException;
|
|
|
|
import java.util.Queue;
|
|
|
|
|
2011-09-30 00:26:50 +00:00
|
|
|
import avian.Atomic;
|
|
|
|
|
2014-03-03 23:02:12 +00:00
|
|
|
public class ConcurrentLinkedQueue<T> implements Queue<T> {
|
2011-09-30 00:26:50 +00:00
|
|
|
private static final long QueueHead;
|
|
|
|
private static final long QueueTail;
|
|
|
|
private static final long NodeNext;
|
|
|
|
|
|
|
|
static {
|
|
|
|
try {
|
|
|
|
QueueHead = Atomic.getOffset
|
|
|
|
(ConcurrentLinkedQueue.class.getField("head"));
|
|
|
|
|
|
|
|
QueueTail = Atomic.getOffset
|
|
|
|
(ConcurrentLinkedQueue.class.getField("tail"));
|
|
|
|
|
|
|
|
NodeNext = Atomic.getOffset
|
|
|
|
(Node.class.getField("next"));
|
|
|
|
} catch (NoSuchFieldException e) {
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-23 21:19:41 +00:00
|
|
|
private volatile Node<T> head = new Node<T>(null, null);
|
2011-09-30 00:26:50 +00:00
|
|
|
private volatile Node<T> tail = head;
|
|
|
|
|
2014-03-03 23:02:12 +00:00
|
|
|
@Override
|
2011-11-07 22:52:42 +00:00
|
|
|
public void clear() {
|
2014-03-03 23:02:12 +00:00
|
|
|
// TODO - can we safely make this O(1)?
|
2011-11-07 22:52:42 +00:00
|
|
|
while (poll() != null) { }
|
|
|
|
}
|
|
|
|
|
2014-03-03 23:02:12 +00:00
|
|
|
@Override
|
|
|
|
public boolean offer(T element) {
|
|
|
|
add(element);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2011-09-30 00:26:50 +00:00
|
|
|
public boolean add(T value) {
|
2013-12-23 21:19:41 +00:00
|
|
|
Node<T> n = new Node<T>(value, null);
|
2011-09-30 00:26:50 +00:00
|
|
|
while (true) {
|
|
|
|
Node<T> t = tail;
|
|
|
|
Node<T> next = tail.next;
|
|
|
|
if (t == tail) {
|
|
|
|
if (next != null) {
|
|
|
|
Atomic.compareAndSwapObject(this, QueueTail, t, next);
|
|
|
|
} else if (Atomic.compareAndSwapObject(tail, NodeNext, null, n)) {
|
|
|
|
Atomic.compareAndSwapObject(this, QueueTail, t, n);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-03-03 23:02:12 +00:00
|
|
|
@Override
|
2011-09-30 00:26:50 +00:00
|
|
|
public T peek() {
|
|
|
|
return poll(false);
|
|
|
|
}
|
|
|
|
|
2014-03-03 23:02:12 +00:00
|
|
|
@Override
|
|
|
|
public T element() {
|
|
|
|
T result = peek();
|
|
|
|
if (result == null) {
|
|
|
|
throw new NoSuchElementException();
|
|
|
|
} else {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2011-09-30 00:26:50 +00:00
|
|
|
public T poll() {
|
|
|
|
return poll(true);
|
|
|
|
}
|
|
|
|
|
2014-03-03 23:02:12 +00:00
|
|
|
@Override
|
|
|
|
public T remove() {
|
|
|
|
T result = poll();
|
|
|
|
if (result == null) {
|
|
|
|
throw new NoSuchElementException();
|
|
|
|
} else {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-11 21:54:43 +00:00
|
|
|
private T poll(boolean remove) {
|
2011-09-30 00:26:50 +00:00
|
|
|
while (true) {
|
|
|
|
Node<T> h = head;
|
|
|
|
Node<T> t = tail;
|
|
|
|
Node<T> next = head.next;
|
|
|
|
|
|
|
|
if (h == head) {
|
|
|
|
if (h == t) {
|
|
|
|
if (next != null) {
|
|
|
|
Atomic.compareAndSwapObject(this, QueueTail, t, next);
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
T value = next.value;
|
|
|
|
if ((! remove)
|
|
|
|
|| Atomic.compareAndSwapObject(this, QueueHead, h, next))
|
|
|
|
{
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static class Node<T> {
|
|
|
|
public volatile T value;
|
|
|
|
public volatile Node<T> next;
|
|
|
|
|
|
|
|
public Node(T value, Node<T> next) {
|
|
|
|
this.value = value;
|
|
|
|
this.next = next;
|
|
|
|
}
|
|
|
|
}
|
2014-03-03 23:02:12 +00:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public int size() {
|
|
|
|
// TODO - implement
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isEmpty() {
|
|
|
|
return size() == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean contains(Object element) {
|
|
|
|
// TODO - implement
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean containsAll(Collection<?> c) {
|
|
|
|
// TODO - implement
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean addAll(Collection<? extends T> collection) {
|
|
|
|
// TODO - implement
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean remove(Object element) {
|
|
|
|
// TODO - implement
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean removeAll(Collection<?> c) {
|
|
|
|
// TODO - implement
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Object[] toArray() {
|
|
|
|
// TODO - implement
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public <S> S[] toArray(S[] array) {
|
|
|
|
// TODO - implement
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Iterator<T> iterator() {
|
|
|
|
// TODO - implement
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
2011-09-30 00:26:50 +00:00
|
|
|
}
|