java实现链式双端队列Object版本

 1,LinkedListDeque:双端队列、加入了游标遍历模式,顺序迭代的效率能够约等于数组遍历的效率;

 2,ConcurrentLinkedListDeque:线程安全的双端队列,使用SerialConvertor线程串行方法,将同时访问的多个线程串行化,并依据进入次序,依次执行;


import java.util.concurrent.ConcurrentHashMap;
 
/**
 * 双端链表队列
 * @author huwei
 */
public class LinkedListDeque {
 
	/**
	 * 队列容量
	 * 	指定队列容纳数据的边界,超出容量不能存入
	 * 默认为Integer.MAX_VALUE
	 */
	private int capacity;
	
	/**
	 * 当前数据数量
	 */
	private int size;
	
	final private Node DEFAULT_TAIL = new Node();
	
	final private Node DEFAULT_HEAD = new Node();
	
	/**
	 * 尾
	 */
	private Node tail;
	
	/**
	 * 头
	 */
	private Node head;
	
	private ConcurrentHashMap<Thread, Cursor> cursors = new ConcurrentHashMap<Thread, LinkedListDeque.Cursor>();
	
	public LinkedListDeque() {
		this(Integer.MAX_VALUE);
	}
 
	public LinkedListDeque(int capacity) {
		this.capacity = capacity;
		initHeadAndTail();
	}
	
	private void initHeadAndTail() {
		tail = DEFAULT_TAIL;
		head = DEFAULT_HEAD;
		size = 0;
		relateNode(head ,tail);
	}
	
	public int capacity() {
		return capacity;
	}
	
	public Node addFirst(Object val) {
		return addNode(head, val, head.getNext());
	}
	
	public Node addLast(Object val) {
		return addNode(tail.getPrev(), val, tail);
	}
	
	private Node addNode(Node prev ,Object val ,Node next) {
		checkBound();
		Node node = createNode(val);
		relateNode(prev ,node);
		relateNode(node ,next);
		incrSize();
		return node;
	}
	
	public Node insertBefore(int index ,Object val) {
		Node node = findNode(index);
		return addNode(node.getPrev(), val, node);
	}
	
	public Node insertAfter(int index ,Object val) {
		return insertBefore(++index, val);
	}
	
	public Node insertBefore(Node node ,Object val) {
		checkNull(node);
		if(!containsNode(node)) {
			throw new RuntimeException("node is not exists!!");
		}
		return addNode(node.getPrev(), val, node);
	}
	
	private boolean containsNode(Node node) {
		Node temp = node;
		while(temp.getPrev() != null) {
			temp = temp.getPrev();
		}
		return temp == head;
	}
	
	public Node insertAfter(Node node,Object val) {
		return insertBefore(node == null ? null : node.getNext(), val);
	}
	
	private void checkNull(Object obj) {
		if(null == obj) {
			throw new RuntimeException("obj is null");
		}
	}
	
	private Node findNode(int index) {
		checkBound();
		checkCursor(index);
		return  cursor0(index).node;
	}
	
	private void checkCursor(int index) {
		if(index >= size || index < 0) {
			throw new RuntimeException("index out bound size =" + size +" ,index = " +index);
		}
	}
	
	public Node pollFirst() {
		return releaseNode(getFirst());
	}
	
	public Node pollLast() {
		return releaseNode(getLast());
	}
	
	public Node getFirst() {
		return head.getNext() == tail ? null : head.getNext();
	}
	
	public Node getLast() {
		return tail.getPrev() == head ? null : tail.getPrev();
	}
	
	/**
	 * 建议使用游标
	 * @param index
	 * @return
	 */
	public Node get(int index) {
		return findNode(index);
	}
	
	/**
	 * 使用游标的方式遍历节点
	 * @param index 游标
	 * @return
	 */
	public Node cursor(int index) {
		checkCursor(index);
		Node result = null;
		
		Thread current = Thread.currentThread();
		Cursor cursor = cursors.get(current);
		if(cursor == null){
			cursor = cursor0(index);
		}else {
			cursor = cursor0(index ,cursor.cursor ,cursor.node);
		}
		
		result = cursor.node;
		
		if(cursor.node.getNext() == tail) {
			System.out.println("删除游标");
			removeCursor();
		}
		else {
			cursors.put(current, cursor);
		}
		
		return result;
	}
	
	private Node findNext(int count ,Node head) {
		Node temp = head;
		int tCount = 0;
		while(temp.getNext() != null) {
			if(count == tCount ++) {
				return temp;
			}
			temp = temp.getNext();
		}
		
		return null;
	}
	
	private Node findPrev(int count ,Node tail) {
		Node temp = tail;
		int tCount = 0;
		while(temp.getPrev() != null) {
			if(count == tCount ++) {
				return temp;
			}
			temp = temp.getPrev();
		}
		
		return null;
	}
	
	public void removeCursor() {
		cursors.remove(Thread.currentThread());
	}
	
	private Cursor cursor0(int index) {
		Node node = null;
		if(index > size / 2) {
			node = findPrev(size - index, tail);
		}
		else {
			node = findNext(index, head.getNext());
		}
		return new Cursor(index ,node);
	}
	
	private Cursor cursor0(int index ,int cursor ,Node node) {
		Node result = null;
		if(index > cursor) {
			if(size - index > index - cursor) {
				result = findNext(index - cursor, node);
			}
			else {
				result = findPrev(size - index, tail);
			}
		}
		else if(cursor - index > index) {
			result = findNext(index, head.getNext());
		}
		else {
			result = findPrev(cursor - index, node);
		}
		
		return new Cursor(index, result);
	}
	
	public int contains(Object val) {
		Node temp = head.getNext();
		int index = -1;
		while(temp.getNext() != null && ++index < size) {
			if(temp.getData() == val || (val != null && val.equals(temp.getData()))) {
				return index; 
			}
			temp = temp.getNext();
		}
		return -1;
	}
	
	private Node findFisrt(Object val) {
		Node temp = head.getNext();
		while(temp.getNext()!= null) {
			if(temp.getData() == val || (val != null && val.equals(temp.getData()))) {
				return temp;
			}
			temp = temp.getNext();
		}
		return null;
	}
	
	private Node findLast(Object val) {
		Node temp = tail.getPrev();
		while(temp.getPrev() != null) {
			if(temp.getData() == val || (val != null && val.equals(temp.getData()))) {
				return temp;
			}
			temp = temp.getPrev();
		}
		return null;
	}
	
	public void remove(Object val) {
		removeFirst(val);
	}
	
	public void removeFirst(Object val) {
		releaseNode(findFisrt(val));
	}
	
	private Node releaseNode(Node node) {
		if(node != null) {
			relateNode(node.getPrev(), node.getNext());
			decrSize();
		}
		return node;
	}
	
	public void removeLast(Object val) {
		Node node = findLast(val);
		releaseNode(node);
	}
	
	public void removeAll(Object val) {
		Node temp = tail.getPrev();
		while(temp.getPrev() != null) {
			if(temp.getData() == val || (val != null && val.equals(temp.getData()))) {
				releaseNode(temp);
			}
			temp = temp.getPrev();
		}
	}
	
	public void clear() {
		initHeadAndTail();
	}
	
	public int size() {
		return size;
	}
	
	public boolean empty() {
		return size == 0;
	}
	
	private void checkBound() {
		if(size == capacity) {
			throw new RuntimeException(LinkedListDeque.class.getName() +" add ele out bound ,current size="+size+";capacity="+capacity);
		}
	}
	
	private synchronized void incrSize() {
		++size;
	}
	
	private synchronized void decrSize() {
		--size;
	}
	
	private Node createNode(Object val) {
		return new Node(val,null,null);
	}
	
	private void relateNode(Node prev, Node next) {
		prev.setNext(next);
		next.setPrev(prev);
	}
	
	/**
	 * 游标
	 *  用于使用下标访问的快速迭代方式
	 * @author huwei
	 */
	private class Cursor {
		int cursor;
		Node node;
		public Cursor(int index, Node node2) {
			cursor = index;
			node = node2;
		}
	}
}


/**
 * 线程安全的链表双端队列
 * @author huwei
 *
 */
public class ConcurrentLinkedListDeque {
 
	private LinkedListDeque container;
	
	private SerialConvertor serialConvertor = new SerialConvertor();
	
	public ConcurrentLinkedListDeque() {
		this(Integer.MAX_VALUE);
	}
	
	public ConcurrentLinkedListDeque(int capacity) {
		container = new LinkedListDeque(capacity);
	}
	
	public int capacity() {
		return container.capacity();
	}
	
	public boolean empty() {
		return container.empty();
	}
	
	public Node addFirst(Object val) {
		serialConvertor.addTask();
		Node temp = container.addFirst(val);
		serialConvertor.pollTask();
		return temp;
	}
	
	public Node addLast(Object val) {
		serialConvertor.addTask();
		Node temp = container.addLast(val);
		serialConvertor.pollTask();
		return temp;
	}
	
	public Node insertBefore(int index ,Object val) {
		serialConvertor.addTask();
		
		Node temp = container.insertBefore(index, val);
		
		serialConvertor.pollTask();
		return temp;
	
	}	
	public Node insertAfter(int index ,Object val) {
		serialConvertor.addTask();
		
		Node temp = container.insertAfter(index, val);
		
		serialConvertor.pollTask();
		return temp;
	}
	
	public Node insertBefore(Node node ,Object val) {
		serialConvertor.addTask();
		Node temp = container.insertBefore(node, val);
		serialConvertor.pollTask();
		return temp;
	}
	
	public Node insertAfter(Node node,Object val) {
		serialConvertor.addTask();
		Node temp = container.insertAfter(node, val);
		serialConvertor.pollTask();
		return temp;
	}
	
	public Node pollFirst() {
		serialConvertor.addTask();
		
		Node temp = container.pollFirst();
		
		serialConvertor.pollTask();
		return temp;
	}
	
	public Node pollLast() {
		serialConvertor.addTask();
		
		Node temp = container.pollLast();
		
		serialConvertor.pollTask();
		return temp;
	}
	
	public Node getFirst() {
		return container.getFirst();
	}
	
	public Node getLast() {
		return container.getLast();
	}
	
	public Node get(int index) {
		return container.get(index);
	}
	
	public Node cursor(int index) {
		return container.cursor(index);
	}
	
	public void removeCursor() {
		container.removeCursor();
	}
	
	public int contains(Object val) {
		return container.contains(val);
	}
	
	public void remove(Object val) {
		removeFirst(val);
	}
	
	public void removeFirst(Object val) {
		serialConvertor.addTask();
		container.removeFirst(val);
		serialConvertor.pollTask();
	}
	
	public void removeLast(Object val) {
		serialConvertor.addTask();
		container.removeLast(val);
		serialConvertor.pollTask();
	}
	
	public void removeAll(Object val) {
		serialConvertor.addTask();
		container.removeAll(val);
		serialConvertor.pollTask();
	}
	
	public void clear() {
		serialConvertor.addTask();
		container.clear();
		serialConvertor.pollTask();
	}
	
	public int size() {
		return container.size();
	}
	
	private class SerialConvertor {
		
		private LinkedListDeque task = new LinkedListDeque(10000);
		
		volatile private Thread before = null;
		
		
		void addTask() {
			SerialState ss = new SerialState(Thread.currentThread());
			synchronized (this) {
				if(before == null || before == ss.thread) {
					before = ss.thread;
					return;
				}
				addState(ss);
			}
			
			synchronized (ss.thread) {
				ss.waiting = true;
				try {
					ss.thread.wait();
				} catch (Exception e) {
					//线程被中断
					removeState(ss);
				}
			}
		}
		
		void pollTask() {
			SerialState ss = null;
			while((ss = pollTaskAndChangeBefore()) != null) {
				
				if(!ss.waiting) {
					addState(ss);
					Thread.yield();
					continue;
				}
				
				synchronized (ss.thread) {
					ss.thread.notifyAll();
					break;
				}
			}
		}
		
		synchronized SerialState pollTaskAndChangeBefore() {
			SerialState ss = pollState();
			before = ss == null ? null : ss.thread;
			return ss;
		}
		
		synchronized void addState(SerialState state) {
			task.addLast(state);
		}
		
		synchronized SerialState pollState() {
			Node node = task.pollFirst();
			return node == null ? null : (SerialState)node.getData();
		}
		
		synchronized void removeState(SerialState state) {
			task.remove(state);
		}
		
		class SerialState {
			volatile Thread thread;
			volatile boolean waiting = false;
			public SerialState(Thread t) {
				thread = t;
			}
		}
	}
}


public class Node {
	// 真实数据
	private Object data;
	/**
	 * 上一个节点
	 */
	private Node prev;
	/**
	 * 下一个节点
	 */
	private Node next;
	/**
	 * @return the data
	 */
	public Object getData() {
		return data;
	}
	/**
	 * @param data the data to set
	 */
	public void setData(Object data) {
		this.data = data;
	}
	/**
	 * @return the prev
	 */
	public Node getPrev() {
		return prev;
	}
	/**
	 * @param prev the prev to set
	 */
	public void setPrev(Node prev) {
		this.prev = prev;
	}
	/**
	 * @return the next
	 */
	public Node getNext() {
		return next;
	}
	/**
	 * @param next the next to set
	 */
	public void setNext(Node next) {
		this.next = next;
	}
	public Node(Object data, Node prev, Node next) {
		this.data = data;
		this.prev = prev;
		this.next = next;
	}
	public Node() {
	}

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值