一、ArrayBlockingQueue:是一个阻塞式的队列,在内部维护了一个定长数组,需要在声明队列的时候确定其大小,其大小之后不可修改,内部只有一个全局变量的锁,因此添加数据和删除数据的时候只能有1个被执行,不允许并行执行,该锁生成两个对象(notEmpty对象、notFull对象)
属性:
/** 存储队列元素的数组 */ final Object[] items; /** 取数据的索引,用于 take, poll, peek or remove方法 */ int takeIndex; /**存数据的索引,用于 put, offer, or add 方法*/ int putIndex; /** 元素个数 */ int count; /** 可重入锁 */ final ReentrantLock lock; /** 等待取数据锁 */ private final Condition notEmpty; /** 等待存数据锁*/ private final Condition notFull; |
二、LinkedBlockingQueue:使用链表完成队列操作的阻塞队列,内部使用放锁和拿锁,这两个锁实现阻塞,添加数据和删除数据是可以并行执行的,但是只能有1个线程各自执行
属性:
/** 容量大小, or Integer.MAX_VALUE if none */ private final int capacity; /** 元素个数,因为有两个锁,存在竞争条件 */ private final AtomicInteger count = new AtomicInteger(0); /** * 头结点 * Invariant: head.item == null */ private transient Node<E> head; /** * 尾结点 * Invariant: last.next == null */ private transient Node<E> last; /** 拿数据的锁 */ private final ReentrantLock takeLock = new ReentrantLock(); /** 那数据的锁的条件对象 */ private final Condition notEmpty = takeLock.newCondition(); /** 存数据的锁 */ private final ReentrantLock putLock = new ReentrantLock(); /** 存数据的锁的条件对象 */ private final Condition notFull = putLock.newCondition(); |
常用方法:
①添加
1)、add(E e)【将元素加入队列,队列满时抛异常】:
public static void main(String[] args) { ArrayBlockingQueue<String> aQueue = new ArrayBlockingQueue<String>(3); aQueue.add("a"); aQueue.add("b"); aQueue.add("c"); aQueue.add("d"); aQueue.add("e"); System.out.println(aQueue.size()); } result:抛queue full异常 |
2)、offer(E e)【将元素加入队列,队列满时返回false,加入失败】
public static void main(String[] args) { ArrayBlockingQueue<String> aQueue = new ArrayBlockingQueue<String>(3); aQueue.offer("a"); aQueue.offer("b"); aQueue.offer("c"); aQueue.offer("d"); System.out.println(aQueue.offer("d")); System.out.println(aQueue.size()); } result:false 3 |
2.1)offer(E e,long time,TimeUtil util)【将元素加入队列,队列满时等待设定的时间如果还是失败返回false,加入失败】
public static void main(String[] args) { ArrayBlockingQueue<String> aQueue = new ArrayBlockingQueue<String>(3); try { aQueue.offer("a"); aQueue.offer("a"); System.out.println(aQueue.offer("b", 3000, TimeUnit.SECONDS)); System.out.println(aQueue.offer("d", 3000, TimeUnit.MILLISECONDS)); System.out.println(aQueue.size()); } catch (InterruptedException e) { e.printStackTrace(); } } result:true false 3 |
3).put(E e)【将元素加入队列,队列满时进入阻塞状态,等待成功加入】
public static void main(String[] args) { ArrayBlockingQueue<String> aQueue = new ArrayBlockingQueue<String>(3); try { aQueue.put("a"); aQueue.put("b"); aQueue.put("c"); System.out.println("d阻塞中"); aQueue.put("d"); System.out.println(aQueue.size()); } catch (InterruptedException e) { e.printStackTrace(); } } result:d阻塞中 |
②获取
1)、poll()【从队列中获取元素,原元素删除,如果队列为空,返回null】
public static void main(String[] args) { ArrayBlockingQueue<String> aQueue = new ArrayBlockingQueue<String>(3); aQueue.offer("a"); aQueue.offer("b"); for (int i = 0; i < 3; i++) { System.out.println(aQueue.poll()); } } result:a b null |
1.1)、poll(long time,TimeUtil util)【从队列中获取元素,原元素删除,如果队列为空,等待设定的时间,如队列还为空,返回null】
public static void main(String[] args) { ArrayBlockingQueue<String> aQueue = new ArrayBlockingQueue<String>(3); aQueue.offer("a"); aQueue.offer("b"); try { System.out.println(aQueue.poll(3000, TimeUnit.MILLISECONDS)); System.out.println(aQueue.poll(3000, TimeUnit.MILLISECONDS)); System.out.println(aQueue.poll(3000, TimeUnit.MILLISECONDS)); } catch (InterruptedException e) { e.printStackTrace(); } } result:a b null |
2)、take()【从队列中获取元素,原元素删除,如果队列为空,则进入阻塞状态,直到取到数据】
public static void main(String[] args) { ArrayBlockingQueue<String> aQueue = new ArrayBlockingQueue<String>(3); aQueue.offer("a"); aQueue.offer("b"); try { System.out.println(aQueue.take()); System.out.println(aQueue.take()); System.out.println("获取队列阻塞中"); System.out.println(aQueue.take()); } catch (InterruptedException e) { e.printStackTrace(); } } result:a b "获取队列阻塞中 |
3)、peek()【从队列中获取当前元素(即最开始插入的元素,队列的首位),原元素还在,如果队列为空,则返回null】
public static void main(String[] args) { ArrayBlockingQueue<String> aQueue = new ArrayBlockingQueue<String>(3); aQueue.offer("g"); aQueue.offer("b"); System.out.println(aQueue.peek()); System.out.println(aQueue.poll()); System.out.println(aQueue.peek()); System.out.println(aQueue.poll()); System.out.println(aQueue.peek()); System.out.println(aQueue.size()); } result:g b b null 0 |