一、前言

      BlockingQueue是一个阻塞队列,而且是当下非常实用的可以解决多线程下并发问题,它是再同一时刻只有一个线程可以处理入队或者出队的容器,这样可以让程序员不用考虑多线程的逻辑,只要处理好自己的业务逻辑就可以了;   并且对于生产者和消费者场景,BlockingQueue是最好的的容器;

二、BlockingQueue队列的几个主要方法

     入队:

        offer(E e):如果队列没满,立即返回true; 如果队列满了,立即返回false-->不阻塞

        put(E e):如果队列满了,一直阻塞,直到队列不满了或者线程被中断-->阻塞

        offer(E e, long timeout, TimeUnit unit):在队尾插入一个元素,,如果队列已满,则进入等待,直到出现以下三种情况:-->阻塞

        被唤醒

       等待时间超时

       当前线程被中断

     出队:

        poll():如果没有元素,直接返回null;如果有元素,出队

        take():如果队列空了,一直阻塞,直到队列不为空或者线程被中断-->阻塞

        poll(long timeout, TimeUnit unit):如果队列不空,出队;如果队列已空且已经超时,返回null;如果队列已空且时间未超时,则进入等待,直到出现以下三种情况:

        被唤醒

       等待时间超时

       当前线程被中断

 在Java中,BlockingQueue是一个接口,它的实现类有ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue等,它们的区别主要体现在存储结构上或对元素操作上的不同,但是对于take与put操作的原理,却是类似的

再这里主要拿ArrayBlockingQueue和LinkedBlockingQueue两个队列来讲解源码;

ArrayBlockingQueue源码解析

   主要几个属性:

   《BlockingQueue讲解》_阻塞队列

 

put方法:

 《BlockingQueue讲解》_多线程_02

 

take方法

 《BlockingQueue讲解》_出队_03

 

 总结: ArrayBlockingQueue阻塞队列,首先就是判断当前队列中有元素, 如果当前元素没有满,出队线程抢到锁,然后进行入队,假如队列已满,那么这时候出队线程就会释放锁,然后进行阻塞,并且进入到条件队列中,如果下一个唤醒的还是入队线程,看到队列已然是满的就会接着还是进入到条件队列中一直阻塞,依次交替然后等到出队线程获取锁,然后进行出队消费元素,队列只要有空闲区域,那么就是来回切换通知入队线程唤醒抢锁,进行加元素,出队再次枪锁,进行出队(循环进行);

 

LinkedBlockingQueue源码详解

 主要属性:

《BlockingQueue讲解》_出队_04

 

put 方法

 《BlockingQueue讲解》_阻塞队列_05

 

take方法

 《BlockingQueue讲解》_等待时间_06

 

 总结:LinkedBlockingQueue队列,分别再出队和入队各自的锁, 都是当元素队列中为空,就从条件队列切换成加锁队列中唤醒入队线程进行添加元素,如果元素队列中不为空,那么就通知出队条件队列,有出队条件队列切换到加锁队列,然后唤醒加锁,然后进行消费元素(出队);

 

 

本人工作3年中级菜鸟程序员, 最近想回顾一下知识,做了一些简单总结同时也为了自己今后复习方便,如果有逻辑错误,大家体谅,同时也希望大牛们能给出正确答案让我改正,谢谢!