使用 Treiber 算法(Treiber,1986)构造的非阻塞栈

22 篇文章 2 订阅
11 篇文章 1 订阅
这篇博客介绍了如何利用Java的AtomicReference类实现一个非阻塞的ConcurrentStack。栈由Node元素构成,每个Node包含一个值和指向下一个元素的链接。push方法通过CAS操作将新节点插入栈顶,而pop方法则从栈顶移除元素。整个过程确保了在并发环境中的线程安全和一致性。
摘要由CSDN通过智能技术生成

读《Java并发编程实战》笔记。

import java.util.concurrent.atomic.AtomicReference;

/**
 * 使用 Treiber 算法(Treiber,1986)构造的非阻塞栈
 * <p>
 *
 * @author hyl
 * @version v1.0: ConcurrentStack.java, v 0.1 2020/10/22 17:18 $
 */
public class ConcurrentStack<E> {

    AtomicReference<Node<E>> top = new AtomicReference<>();

    public void push(E item) {
        Node<E> newHead = new Node<>(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;
        }
    }
}

说明:

ConcurrentStack 中给出了如何通过原子引用来构建栈的示例。

  • 栈是由Node元素构成的一个链表,其中栈顶作为根节点,并且在每个元素中都包含了一个值以及指向下一个元素的连接。
  • push 方法创建一个新的节点,该节点的 next 域指向当前的栈顶,然后使用 CAS 把这个新节点放入栈顶。如果在开始插入节点时,位于栈顶的节点没有发生变化,那么 CAS 就会成功,如果栈顶节点发生了变化,那么 CAS 就会失败,而 push 方法会根据栈的当前状态来更新节点,并且再次尝试。
  • 无论那种情况,在 CAS 执行完成后,栈仍会处于一致的状态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值