Java无锁堆栈详解

版权声明:本文为博主原创文章,转载请注明。 https://blog.csdn.net/shf4715/article/details/70850392

有这样一个题目: 实现一个无锁的Stack,并写一段测试代码(多线程访问),证明这个Stack是线程安全的。

分析:

出于节省内存空间的考虑,使用链式的存储结构来实现。
实现该堆栈的思想为:
1、压入一个新节点时,将旧结点存入新结点中。弹出时将顶部节点中存入的上一节点取出并将其设为站定。
2、使用无锁的实现类AtomicReference作为安全的无锁局部变量对元素进行暂存。
以下为实现代码,具体解释参见注释。

static LockFreeStack<Object> stack = new LockFreeStack<>();

    @Test
    public void test01() throws Exception {
        // 实现一个无锁的Stack,并写一段测试代码(多线程访问),证明这个Stack是线程安全的。给出程序以及运行的截图。
        Push [] pushs = new Push[10];
        Pop [] pop = new Pop[10];
        for(int i = 0; i < 10; i++) {
            pushs[i] = new Push();
            pop[i] = new Pop();
        }
        for(int i = 0; i < 10; i++) {
            pushs[i].start();
            pop[i].start();
        }
        for(int i = 0; i < 10; i++) {
            pushs[i].join();
            pop[i].join();
        }

    }

    static class Push extends Thread {
        @Override
        public void run() {
            for(;;) {
                stack.push("Random->"+Math.random());
            }
        }
    }

    static class Pop extends Thread {
        @Override
        public void run() {
            for(;;) {
                System.out.println("已出栈:" + stack.pop());
            }
        }
    }

    static class LockFreeStack<V> {

        private AtomicReference<Node<V>> top = new AtomicReference<>();

        public LockFreeStack() {
        }

        public void push(V o) {
            Node<V> nextValue = new Node<V>(o, null);
            Node<V> oldValue = null;
            do {
                oldValue = top.get();
                nextValue.setNext(oldValue); //新节点存入旧节点
            } while (!top.compareAndSet(oldValue, nextValue));

        }

        public V pop() {
            Node<V> oldValue = null;
            Node<V> nextValue = null;
            do {
                oldValue = top.get();
                if (oldValue == null) {
                    continue;//oldValue为空则栈内是空的
                }
                nextValue = oldValue.getNext();
                //while中oldValue == null 是指在空栈的情况下重试
            } while (oldValue == null || !top.compareAndSet(oldValue, nextValue));  
            return oldValue.getValue();
        }

        class Node<T> {
            private T value;
            private Node<T> next;

            public Node(T value, Node<T> next) {
                super();
                this.value = value;
                this.next = next;
            }

            public T getValue() {
                return value;
            }

            public void setValue(T value) {
                this.value = value;
            }

            public Node<T> getNext() {
                return next;
            }

            public void setNext(Node<T> next) {
                this.next = next;
            }

        }

    }
展开阅读全文

没有更多推荐了,返回首页