java并发编程-JUC之阻塞队列

      阻塞队列是JUC包下的重要的数据结构,阻塞队列(BlockingQueue)提供了 线程安全的队列询问方式 ,当阻塞队列进行插入 数据 的时候,如果队列已满,则线程处于等待状态,从阻塞队列取出数据的时候,如果 队列为空,则线程处于阻塞指导处于非空。在 JUC包中,很多高级同步类都是 基于BlockingQueue来 实现的。

1.BlockingQueue四组方法

BlockingQueue具有四种不同的方法用于插入,移除以及 队列中的元素进行检查,如果请求 操作不能 立即执行的话,每个方法的表现 也不同。具体如下:
java并发编程-JUC之阻塞队列_第1张图片

2.BlockingQueue实现类

BlockingQueue是 一个接口,JDK1.8下 的UML类图如下:
java并发编程-JUC之阻塞队列_第2张图片

ArrayBlockingQueue:
       有界阻塞队列,内部实现是将 队列 对象 放入 一个数组中,有界也就意味着,它不能够存储无限多数量的元素。它有一个同一时间能够存储元素数量的上限。你可以在对其初始化的时候设定这个上限,但之后就无法对这个上限进行修改了
java并发编程-JUC之阻塞队列_第3张图片

DelayQueue:
       DelayQueue 对元素进行持有直到一个特定的延迟到期。注入其中的元素必须实现java.util.concurrent.Delayed 接口,具体用用参考java并发之DelayQueue实际运用示例

LinkedBlockingQueue:
       LinkedBlockingQueue 中也有两个 Node 分别用来存放首尾节点,并且里面有个初始值为 0 的原子变量 count用来记录队列元素个数,另外里面有两个 ReentrantLock 的独占锁,分别用来控制元素入队和出队加锁,其中 takeLock用来控制同时只有一个线程可以从队列获取元素,其他线程必须等待, putLock 控制同时只能有一个线程可以获取锁去添加元素,其他线程必须等待。另外 notEmpty 和 notFull 用来实现入队和出队的同步。 另外由于出入队是两个非公平独占锁,所以可以同时又一个线程入队和一个线程出队,其实这个是个生产者-消费者模型。

PriorityBlockingQueue:
       PriorityBlockingQueue 是带优先级的无界阻塞队列,每次出队都返回优先级最高的元素,是二叉树最小堆的现,该队列能够存储的对象必须 实现java.lang.Comparable 接口。或者在构造函数中 初入 java.lang.Comparable的 实现,
java并发编程-JUC之阻塞队列_第4张图片
       如图 PriorityBlockingQueue 内部有个数组 queue 用来存放队列元素, size 用来存放队列元素个数,allocationSpinLockOffset 是用来在扩容队列时候做 cas 的,目的是保证只有一个线程可以进行扩容。

SynchronousQueue:
      它的特别之处在于它内部没有容器,一个生产线程,当它生产产品(即put 的时候),如果当前没有人想要消费产品(即当前没有线程执行 take),此生产线程必须阻塞,等待一个消费线程调用 take 操作, take 操作将会唤醒该生产线程,同时消费线程会获取生产线程的产品(即数据传递),这样的一个过程称为一次配对过程(当然也可以先 take 后 put,原理是一样的)
java并发编程-JUC之阻塞队列_第5张图片
运行结果:
java并发编程-JUC之阻塞队列_第6张图片

你可能感兴趣的:(java基础)