非阻塞算法属于并发算法,它们可以安全地派生它们的线程,不通过锁定派生,而是通过低级的原子性的硬件原生形式 —— 例如比较和交换。非阻塞算法的设计与实现极为困难,但是它们能够提供更好的吞吐率,对生存问题(例如死锁和优先级反转)也能提供更好的防御。
AtomicInteger 中的cas操作
自增操作:
public final int getAndIncrement() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return current; } }
自增是通过compareAndSet实现的
expect:期望值
update:如果变量当前值等于期望值,则将update赋给变量
public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); }
Unsafe.compareAndSwapInt(Object obj,longl,int I,int j) 是native方法。
l:对象的内存地址 Unsafe.objectFieldOffset/Unsafe.staticFieldOffset获得
简单的cas实例:
public class Test { public static void main(String[] args) { Test t=new Test(); try { t.increment(10, 20); } catch (Exception e) { e.printStackTrace(); } System.out.println(t.i); } public int i = 10; public void increment(int expect, int update) throws Exception { Unsafe unsafe=Test.getUnsafeInstance(); unsafe.compareAndSwapInt( this, unsafe.objectFieldOffset( this.getClass().getDeclaredField("i")), expect, update); } //获取Unsafe实例 private static Unsafe getUnsafeInstance() throws Exception { Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafeInstance.setAccessible(true); return (Unsafe) theUnsafeInstance.get(Unsafe.class); } }
输出:20
基于CAS的非阻塞并发栈实现
public class ConcurrentStack<E> { AtomicReference<Node<E>> head=new AtomicReference<Node<E>>(); public void push(E item){ Node<E> newHead=new Node<E>(item); Node<E> oldHead; do{ oldHead=head.get(); newHead.next=oldHead; }while(!head.compareAndSet(oldHead, newHead)); } public E pop(){ Node<E> oldHead; Node<E> newHead; do{ oldHead=head.get(); if(oldHead==null) return null; newHead=oldHead.next; }while(!head.compareAndSet(oldHead, newHead)); return oldHead.item; } static class Node<E>{ final E item; Node<E> next; public Node(E item){ this.item=item; } } public static void main(String[] args){ ConcurrentStack<String> st=new ConcurrentStack<String>(); st.push("a"); st.push("b"); System.out.println(st.pop()); } }
基于CAS的非阻塞链表实现
public class LinkedQueue<E> { private AtomicReference<Node<E>> head = new AtomicReference<Node<E>>( new Node<E>(null, null)); private AtomicReference<Node<E>> tail = head; public boolean put(E item) { Node<E> newNode = new Node<E>(item, null); while (true) { Node<E> curTail = tail.get(); Node<E> residue = curTail.next.get(); if (curTail == tail.get()) { if (residue == null) { if(curTail.next.compareAndSet(null, newNode)){ tail.compareAndSet(curTail, newNode); return true; } } else { tail.compareAndSet(curTail, residue); } } } } private static class Node<E> { final E item; final AtomicReference<Node<E>> next; Node(E item, Node<E> next) { this.item = item; this.next = new AtomicReference<Node<E>>(next); } } }
参考资料:
1. http://www.ibm.com/developerworks/cn/java/j-jtp04186/
2. http://aswang.iteye.com/blog/1741871
3. http://javafans.info/java/corejava/15.html