JDK-阻塞队列、非阻塞队列原理

前言

在jdk提供的队列中,有阻塞队列和非阻塞队列
阻塞队列是指:在添加元素的时候,如果队列已经满了,此时会阻塞当前入队的线程,将入队的线程放入到AQS的同步条件队列中,在队列元素出队之后,会尝试唤醒阻塞的线程,阻塞的线程将从条件队列进入到同步等待队列中进行排队;
在出队的时候,也是同样的道理,如果队列中元素为空,就会阻塞出队元素,进入到同步条件队列中,在队列中入队了元素之后,会唤醒阻塞的线程,阻塞的出队线程,从条件队列进入到等待队列中。进行排队,等待获取执行权限

非阻塞队列:在juc中,提供的非阻塞队列,是通过CAS来实现的,也就是说,如果在入队的时候,如果入队失败,会进行CAS自旋。而不是阻塞,进入到条件队列

除了阻塞和非阻塞队列之外,jdk还提供了优先级队里、延迟队列

阻塞队列

阻塞队列中,我比较熟悉的是ArrayBlockingQueue和LinkedBlockingQueue,所以,以这两个为例,来做一个学习

ArrayBlockingQueue

在这里插入图片描述

ArrayBlockingQueue,从名字就可以看出来,内部是数组结构,是有界的,那阻塞是怎么实现的呢?
在ArrayBlockingQueue中,维护了一个ReentrantLock和两个condition

/** Main lock guarding all access */
final ReentrantLock lock;

/** Condition for waiting takes */
private final Condition notEmpty;

/** Condition for waiting puts */
private final Condition notFull;

入队的源码

/**
* 这是入队的操作
* 1.加锁
* 2.判断当前数组中的元素个数等于数组长度,就返回false,表示此时队列已经满了
* 3.入队,入队成功的话,返回true
* 4.解锁
*/
public boolean offer(E e) {
   
  checkNotNull(e);
  final ReentrantLock lock = this.lock;
  lock.lock();
  try {
   
      if (count == items.length)
          return false;
      else {
   
          enqueue(e);
          return true;
      }
  } finally {
   
      lock.unlock();
  }
}

出队的源码

/**
* 这是出队的逻辑
* 1.首先加锁
* 2.如果当前队列中为空,就阻塞,调用condition的await()方法,将当前线程放入到同步条件队列中进行休眠
* 3.如果不为空,正常出队,所谓的出队,就是从数组头部出队,返回对应的元素
* 4.然后释放锁
* @return
* @throws InterruptedException
*/
public E take() throws InterruptedException {
   
  final ReentrantLock lock = this.lock;
  lock.lockInterruptibly();
  try {
   
      while (count == 0)
          notEmpty.await();
      return dequeue()
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值