【Java】使用VarHandler实现无锁Stack
一,概述
java.utils中Stack,本身继承Vector,而Vector部分方法使用synchronized方法加锁,导致Stack本身操作也是加锁操作,相对来说还是有性能开销的。那么怎么实现轻量级无锁且安全的Stack?可以借助VarHandler原子操作实现。仅供参考,其它高性能数据结构优化可参考。
二,实现
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.NoSuchElementException;public class StackWithoutLock<T> {private static final VarHandle TAIL;static {MethodHandles.Lookup l = MethodHandles.lookup();try {TAIL = l.findVarHandle(StackWithoutLock.class, "tail", Node.class);} catch (NoSuchFieldException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}}private final Node<T> HEAD = new Node<>();private int size;private Node<T> tail = HEAD;public void push(T t) {Node<T> oldTail = tail;Node<T> newNode = new Node<>();newNode.value = t;while (!TAIL.compareAndSet(this, oldTail, newNode)) {oldTail = tail;}oldTail.next = newNode;newNode.pre = oldTail;size++;}public T pop() {if (tail == HEAD) {throw new NoSuchElementException("stack empty!");}Node<T> oldTail = tail;Node<T> newTail = tail.pre;while (!TAIL.compareAndSet(this, tail, newTail)) {oldTail = tail;newTail = tail.pre;}size--;return oldTail.value;}public T peek() {if (tail == HEAD) {throw new NoSuchElementException("stack empty!");}return tail.value;}public boolean isEmpty() {return size == 0;}}private static class Node<T> {T value;Node<T> next;Node<T> pre;}
}
三,效果
public static void main(String[] args) {StackWithoutLock<Integer> stack1 = new StackWithoutLock<>();for (int i = 0; i < 5; i++) {stack1.push(i);System.out.println(stack1.peek() + " size=" + stack1.size);}while (!stack1.isEmpty()) {Integer pop = stack1.pop();System.out.println("pop " + pop + " size=" + stack1.size);}}