Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package bestsss.util;
- import java.util.Collection;
- import sun.misc.Unsafe;
- /**
- *
- * @author Stanimir Simeonoff
- * The code is in public domain: http://creativecommons.org/publicdomain/zero/1.0/
- *
- * The implementation is a very basic concurrent linked stack with a size field for each node. The top of the stack contains the real size of the stack.
- * During drain() the entire stack is consumed all at once and the result is reversed.
- */
- public class SCMPLinkedStackAsQueue<E> {
- private final int bound;
- private volatile Node<E> head;
- public SCMPLinkedStackAsQueue(int bound) {
- super();
- if (bound<=0) throw new IllegalArgumentException();
- this.bound = bound;
- }
- private static class Node<E> {
- Node<E> next;
- int size;
- final E item;
- Node(E item){
- this.item = item;
- }
- }
- public boolean offer(E e){
- if (e==null)
- throw new NullPointerException();
- for(final Node<E> h=new Node<E>(e);;){
- Node<E> node = head;
- int size = node!=null?node.size:0;
- if (++size>bound)
- return false;
- h.size = size;
- h.next = node;
- if (casHead(node, h)){
- return true;
- }
- }
- }
- private boolean casHead(Node<E> cmp, Node<E> val){
- return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
- }
- public boolean isEmpty(){return head==null;}
- public int size(){Node<?> node = head; return node!=null?node.size:0;}
- @SuppressWarnings("unchecked")
- public Collection<E> drain(){
- for (Node<E> node; null!=(node= head);){//start from the head,
- if (casHead(node, null)){//consume the entire stack,
- Object[] a=new Object[node.size];//reverse it
- for (;node!=null;node=node.next)
- a[node.size-1]=node.item;
- return (Collection<E>) java.util.Arrays.asList(a);//and return it
- }
- }
- return java.util.Collections.emptyList();
- }
- private static final sun.misc.Unsafe UNSAFE;
- private static final long headOffset;
- static {
- try {
- java.lang.reflect.Field f = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
- f.setAccessible(true);
- UNSAFE = (Unsafe) f.get(null);
- headOffset = UNSAFE.objectFieldOffset(SCMPLinkedStackAsQueue.class.getDeclaredField("head"));
- } catch (Exception e) {
- throw new Error(e);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement