BlockingQueue的实现类

一、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

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值