This example is copied from book "Java Concurrency in Practice".
From this example we can learn that the lock free queue code is not correct for MPMC (multi-producer-multi-consumer) in my previous post.
Actually, lock free means you should guarantee the atomicity of updating a pointer. When you add a new node on top of current stack top, the top node might be poped by another thread. So you should prepare to do that again if that did happen. How to do this? We thus need a CAS operation, if current top is what we saw and we have successfully update the top to a new node, ok, our job is done.
While, lock free queue can be more complicated if you insert one node to the tail since we need to update two pointers at same time, one is a *tail* pointing to the last node and one is its *next* pointer.
I will give one correct queue code in the next post.
From this example we can learn that the lock free queue code is not correct for MPMC (multi-producer-multi-consumer) in my previous post.
Actually, lock free means you should guarantee the atomicity of updating a pointer. When you add a new node on top of current stack top, the top node might be poped by another thread. So you should prepare to do that again if that did happen. How to do this? We thus need a CAS operation, if current top is what we saw and we have successfully update the top to a new node, ok, our job is done.
While, lock free queue can be more complicated if you insert one node to the tail since we need to update two pointers at same time, one is a *tail* pointing to the last node and one is its *next* pointer.
I will give one correct queue code in the next post.
@ThreadSafe
public class ConcurrentStack <E> {
AtomicReference<Node<E>> top = new AtomicReference<Node<E>>();
public void push(E item) {
Node<E> newHead = new Node<E>(item);
Node<E> oldHead;
do {
oldHead = top.get();
newHead.next = oldHead;
} while (!top.compareAndSet(oldHead, newHead));
}
public E pop() {
Node<E> oldHead;
Node<E> newHead;
do {
oldHead = top.get();
if (oldHead == null)
return null;
newHead = oldHead.next;
} while (!top.compareAndSet(oldHead, newHead));
return oldHead.item;
}
private static class Node <E> {
public final E item;
public Node<E> next;
public Node(E item) {
this.item = item;
}
}
}
本文深入解析Java并发编程中的锁自由队列概念,指出常见实现中的错误,并提供正确的代码实现。重点阐述了在多生产者多消费者场景下,如何确保线程安全地更新指针,以及在插入节点时需要处理的复杂情况。
6567

被折叠的 条评论
为什么被折叠?



