欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

java queue源码_Java高并发系列之ArrayBlockingQueue源码解析

发布时间:2024/9/27 46 豆豆
生活随笔 收集整理的这篇文章主要介绍了 java queue源码_Java高并发系列之ArrayBlockingQueue源码解析 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

JUC包下定义了一个接口:BlockingQueue。其实现类有ArrayBlockingQueue等。本文先来介绍一下ArrayBlockingQueue。从字面可以看出,ArrayBlockingQueue是一种基于数组的阻塞队列,阻塞队列在线程池中会经常使用到。

首先来看看ArrayBlockingQueue的类图,如下所示。从类图可以看出,ArrayBlockingQueue继承自AbstractQueue,实现了BlockingQueue接口。

在ArrayBlockingQueue内部有一个数组items,同时定义了takeIndex和putIndex变量。由于是队列,因此一端入队操作,另一端进行出队操作。另外,内部定义了ReentrantLock作为独占锁。

1、构造函数

先来看看其构造函数。其有三给构造函数,不过都是调用这个构造函数。

构造函数的参数需要指定初始容量,同时指定采用公平锁还是非公平锁。从这一点可以看出,ArrayBlockingQueue是一个有界队列。

2、offer函数

offer操作用于向队列尾部插入一个元素,如果空闲则插入元素,如果非空闲,返回true。如果队列满,则返回false。下面让我们来看看offer操作的源码。

从上面的源码可以看出,不管插入成功与否,都会立即返回结果,因此这个方法是非阻塞的,但是也不能保证一定插入元素成功。

3、put函数

从源码中可以看出,put操作首先检查元素是否位空,如果为空,则抛异常。然后进行加锁,然后判断当前队列是否满了,如果满了就阻塞当前线程,然后挂起放入条件队列。当然,这个方式是相应中断的(因为上面lockInterruptibly方法可以响应中断)。如果队列没满,则入队。最后释放锁。

4、poll操作

poll是从队列头部取走元素,其源码如下:

首先进行加锁操作,然后判断当前队列元素是否为0,如果是返回空。否则返回队列头元素。这个方法是不支持响应中断的。至于deque操作,就是去数组中取元素,和普通队列处理逻辑没有区别。

5、take操作

take操作也是从队列头取元素。其源码如下所示:

从源码上可以看出,take也是支持响应中断的。如果队列元素为空,则会阻塞挂起,除非队列有元素被唤醒。也就是这个方法一定要保证取到元素,如果取不到元素,会等到有元素才返回。不像上面的poll方法,取不到就返回null。

6、peek操作

peek操作时查看队列首部的元素,但是不移除。源码如下:

从源码上可以看出,此方法也是非阻塞的。即使队列没有元素也就是会立即返回的(返回null)。不像上面的take操作,没有元素就等到有元素再返回。

7、size操作

此方法是获取队列元素个数的方法,源码如下:

从源码可以看出,size操作时加锁的,因为在定义count变量的时候没有使用volitate修饰,这样通过加锁保证了内存的可见性。这里其实也可以通过putIndex和takeIndex来得到队列元素长度。在Netty框架中的Bytebuf就是这样计算的。

总结

以上是生活随笔为你收集整理的java queue源码_Java高并发系列之ArrayBlockingQueue源码解析的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。