java – 这是(无锁)队列实现线程安全吗?
发布时间:2020-05-24 15:10:37 所属栏目:Java 来源:互联网
导读:我试图在 Java中创建一个无锁队列的实现,主要用于个人学习.队列应该是一个通用的队列,允许任意数量的读者和/或作者同时进行. 你能否回顾一下,并提出任何改进/问题你找到? 谢谢. import java.util.concurrent.atomic.AtomicReference;public class LockFreeQu
|
我试图在 Java中创建一个无锁队列的实现,主要用于个人学习.队列应该是一个通用的队列,允许任意数量的读者和/或作者同时进行. 你能否回顾一下,并提出任何改进/问题你找到? 谢谢. import java.util.concurrent.atomic.AtomicReference;
public class LockFreeQueue<T> {
private static class Node<E> {
E value;
volatile Node<E> next;
Node(E value) {
this.value = value;
}
}
private AtomicReference<Node<T>> head,tail;
public LockFreeQueue() {
// have both head and tail point to a dummy node
Node<T> dummyNode = new Node<T>(null);
head = new AtomicReference<Node<T>>(dummyNode);
tail = new AtomicReference<Node<T>>(dummyNode);
}
/**
* Puts an object at the end of the queue.
*/
public void putObject(T value) {
Node<T> newNode = new Node<T>(value);
Node<T> prevTailNode = tail.getAndSet(newNode);
prevTailNode.next = newNode;
}
/**
* Gets an object from the beginning of the queue. The object is removed
* from the queue. If there are no objects in the queue,returns null.
*/
public T getObject() {
Node<T> headNode,valueNode;
// move head node to the next node using atomic semantics
// as long as next node is not null
do {
headNode = head.get();
valueNode = headNode.next;
// try until the whole loop executes pseudo-atomically
// (i.e. unaffected by modifications done by other threads)
} while (valueNode != null && !head.compareAndSet(headNode,valueNode));
T value = (valueNode != null ? valueNode.value : null);
// release the value pointed to by head,keeping the head node dummy
if (valueNode != null)
valueNode.value = null;
return value;
}
解决方法代码不是线程安全的.考虑putObject(…):public void putObject(T value) {
Node<T> newNode = new Node<T>(value);
Node<T> prevTailNode = tail.getAndSet(newNode);
prevTailNode.next = newNode;
}
第二个语句在前一个节点的下一个指针设置之前添加新节点.这只发生在第三个声明中.因此,有一个窗口,其中下一个是null;即比赛条件. 即使你固定下来,还有一个比较阴险的问题.读取Node对象的下一个字段的线程不一定会看到第二个线程刚刚写入的值.这是Java内存模型的结果.在这种情况下,确保以下读取始终看到较早的书面值的方法是: >声明为volatile,或 编辑:在更详细地阅读getObject()和putObject()的代码时,我可以看到没有什么强制下一个的非空值在putObject中被刷新到内存,没有任何强制getObject从主内存中读取.所以getObject代码可以看到下一个错误的值,导致它在队列中真的有一个元素时返回null. (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
