源码角度了解阻塞队列之ArrayBlockingQueue
【摘要】 源码角度了解阻塞队列之ArrayBlockingQueue put()方法 enqueue()方法 take()方法 dequeue()方法 总结 源码角度了解阻塞队列之ArrayBlockingQueue关于阻塞队列的文章,之前的文章也有所介绍,今天从源码的角度再分析分析,接口是BlockingQueue,它的实现类很多,ArrayBlockingQueue数组实现的环形队列,它定义了队...
源码角度了解阻塞队列之ArrayBlockingQueue
关于阻塞队列的文章,之前的文章也有所介绍,今天从源码的角度再分析分析,接口是BlockingQueue,它的实现类很多,
ArrayBlockingQueue数组实现的环形队列,它定义了队头指针的队尾指针,一个ReentrantLock锁和两个Condition
put()方法
它的put方法:
public void put(E e) throws InterruptedException {
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == items.length)
notFull.await();
enqueue(e);
} finally {
lock.unlock();
}
}
put()方法中在此队列的尾部插入指定元素,如果队列已满,则阻塞等待队列可用。lock.lockInterruptibly()是可中断的锁,当其他线程中断该线程的时候,当前线程获取锁失败,这里调用了enqueue()方法:
enqueue()方法
private void enqueue(E x) {
final Object[] items = this.items;
items[putIndex] = x;
if (++putIndex == items.length)
putIndex = 0;
count++;
notEmpty.signal();
}
插入元素到当前队列中,这个方法是在获取到锁之后才能被调用的
- 放入元素
- 判断索引位置是否已经到队列尾部了,如果是,索引位置回到队头
- 通知其他线程
take()方法
逻辑和put()方法总体上差不多,判断count是否为0,如果为0,阻塞等待,否则调用dequeue()方法,dequeue()方法的逻辑又和enqueue()方法差不多
dequeue()方法
插入元素到当前队列中,这个方法是在获取到锁之后才能被调用的
- 获取索引元素
- 判断索引位置是否已经到队列尾部了,如果是,索引位置回到队头
- count减一
- 唤醒满足notFull条件上的线程
总结
这篇文章从ArrayBlockingQueue的put()方法和take()方法进行分析,ArrayBlockingQueue底层是使用数组实现的,它的这两个方法主要是对数组的操作,但是数组有固定长度,从它的构造方法中也能看出来必须要传入一个容量的参数,它的核心成员变量有count用来记录数组中元素个数,两个指针分别指向放入元素和取出元素的位置,两个Condition表示非空和非满,唤醒线程,实现线程间的交互
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)