Java阻塞队列—BlockingQueue

参考:https://www.cnblogs.com/KingIceMou/p/8075343.htmlhtml

BlockingQueue是一个阻塞队列接口,BlockingQueue基于队列容器实现了插入和取出数据的阻塞,若是队列中没有数据时,取出数据的操做被阻塞直到队列中有数据能被取出;若是队列中数据已经填满,则插入数据的操做将被阻塞,直到队列中有空位可以插入。BlockingQueue实现是线程安全的,全部排队方法都使用内部锁或其余形式的并发控制以原子方式实现其效果,除非在实现中另有说明。基于以上特性咱们能够很轻松的实现生产者-消费者模型。java

BlockingQueue主要有如下方法:数组

//向队列中添加一个元素,成功返回true;该元素不能为null,若是队列已满则抛出IllegalStateException
        boolean add(E e);

        //向队列中添加一个元素,成功返回true;该元素不能为null,若是队列已满则返回false
        boolean offer(E e);

        //向队列中添加一个元素,成功返回true;该元素不能为null,若是队列已满则调用此方法的线程被阻塞等待timeout时间,若是超过了timeout还不能入队则返回false,若是等待过程被中断则抛出InterruptedException
        boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException;

        //向队列中添加一个元素,成功返回true;该元素不能为null,若是队列已满则调用此方法的线程被阻塞等待,直到队列中里面有空间再入队,若是等待过程被中断则抛出InterruptedException 
        void put(E e) throws InterruptedException;

        //取出队列中的头部元素,若是队列为空则调用此方法的线程被阻塞等待,直到有元素能被取出,若是等待过程被中断则抛出InterruptedException
        E take() throws InterruptedException;

        //取出队列中的头部元素,若是队列为空返回null
        E poll();

        //取出队列中的头部元素,若是队列为空则调用此方法的线程被阻塞等待timeout时间,若是超过了timeout尚未元素能被取出则返回null,若是等待过程被中断则抛出InterruptedException
        E poll(long timeout, TimeUnit unit) throws InterruptedException;

        //返回队列中的头部元素,但不从队列中移除该元素,若是队里为空则返回null
        E peek();

        //返回队列的剩余容量,咱们不该该用该方法来判断咱们能不能插入成功,由于可能另外一个线程已经插入了
        int remainingCapacity();

        //从队列中删除指定元素,若是该元素存在则删除该元素并返回true,不然返回false;注意若是队里中存在多个相同元素,该方法只会删除离头最近的那一个
        boolean remove(Object o);

        //判断队列中是否存当前元素
        boolean contains(Object o);

        //将队列中全部元素取出来放到集合c中
        drainTo(Collection<? super E> c)

BlockingQueue的主要实现有:ArrayBlockingQueue、LinkedBlockingQueue、DelayQueue、PriorityBlockingQueue、SynchronousQueue这几种,他们之间须要注意的几点是:安全

  1. ArrayBlockingQueue:基于数组实现,初始化时必须指定队列长度,插入数据和取出数据共用同一个锁对象。
  2. LinkedBlockingQueue:基于链表实现,初始化能够不指定队列长度(默认为Integer.MAX_VALUE,可能发生内存耗尽的状况,因此经量在初始化时指定队列长度),插入数据和取出数据采用独立的锁对象。
  3. DelayQueue中的元素只有当其指定的延迟时间到了,才可以从队列中获取到该元素。DelayQueue是一个没有大小限制的队列,所以往队列中插入数据永远不会被阻塞,而只有获取数据才会被阻塞。
  4. PriorityBlockingQueue基于优先级的阻塞队列(优先级的判断经过构造函数传入的Compator对象来决定),但须要注意的是PriorityBlockingQueue并不会阻塞数据生产者,而只会在没有可消费的数据时,阻塞数据的消费者。所以使用的时候要特别注意,插入数据的速度绝对不能快于取出消费数据的速度,不然容易发生内存耗尽的状况
相关文章
相关标签/搜索