LinkedBlockingQueue是一个阻塞的、线程安全的、由链表实现的双向队列,和ArrayBlockingQueue一样,是最普通也是最常用的阻塞队列。现基于LinkedBlockingQueue源码自我实现一个单向的、简化版的LinkedBlockingQueue.
package com.lzq.newInterview; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class MyLinkedBlockingQueue<E> { private Node<E> head;// 队头 private Node<E> tail;// 队尾 private static final int DEFALT_SIZE = 20; private int size;// 队列最大长度 private int count;// 队列当前容量 private ReentrantLock lock = new ReentrantLock(); private Condition empty = lock.newCondition(); private Condition full = lock.newCondition(); public MyLinkedBlockingQueue() { head = null; tail = null; size = DEFALT_SIZE; } public MyLinkedBlockingQueue(int size) { head = null; tail = null; this.size = size; } // 队列尾部插入元素 public void offer(E e) { if (e == null) return; try { lock.lock(); while (count == size) { full.await(); } if (head == null && tail == null) { Node<E> node = new Node<E>(e, null); head = node; tail = node; } else { Node<E> node = new Node<E>(e, null); tail.next = node; tail = node; } count++; System.out.println("offer: count=" + this.count); empty.signal(); } catch (Exception exp) { exp.printStackTrace(); } finally { lock.unlock(); } } public E poll() { try { lock.lock(); while (count == 0) { empty.await(); } E oldValue = head.value; head = head.next; if (head == null) tail = null; count--; System.out.println("poll: count=" + this.count); full.signal(); return oldValue; } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } return null; } static class Node<E> { Node<E> next; E value; Node(E value, Node<E> next) { this.value = value; this.next = next; } } public static void main(String[] args) { final MyLinkedBlockingQueue<Integer> queue = new MyLinkedBlockingQueue<Integer>(); for (int i = 0; i < 100; i++) { final int num = i; Thread t = new Thread(new Runnable() { public void run() { queue.offer(num); } }); t.start(); } for (int i = 0; i < 100; i++) { Thread t = new Thread(new Runnable() { public void run() { queue.poll(); } }); t.start(); } } }
部分运行结果:
offer: count=1
offer: count=2
offer: count=3
offer: count=4
offer: count=5
offer: count=6
offer: count=7
offer: count=8
offer: count=9
offer: count=10
offer: count=11
offer: count=12
poll: count=11
poll: count=10
poll: count=9
poll: count=8
poll: count=7
poll: count=6
poll: count=5
poll: count=4
poll: count=3
poll: count=2
poll: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
offer: count=2
offer: count=3
poll: count=2
poll: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
offer: count=2
poll: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
offer: count=2
poll: count=1
poll: count=0
offer: count=1
offer: count=2
poll: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
offer: count=2
poll: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
poll: count=0