1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-06-16 18:10:13 +08:00

[docs update]进一步完善ArrayBlockingQueue源码分析

This commit is contained in:
Guide 2023-06-21 14:39:47 +08:00
parent b6e16c8dc3
commit 4c2d59f475
2 changed files with 28 additions and 10 deletions

View File

@ -700,7 +700,7 @@ public boolean contains(Object o) {
新增元素:
| 方法 | 队列满时处理方式 | 方法返回值 |
| ----------------------------------------- | ------------------------------------------------------- | ---------- |
| ----------------------------------------- | -------------------------------------------------------- | ---------- |
| `put(E e)` | 线程阻塞,直到中断或被唤醒 | void |
| `offer(E e)` | 直接返回 false | boolean |
| `offer(E e, long timeout, TimeUnit unit)` | 指定超时时间内阻塞,超过规定时间还未添加成功则返回 false | boolean |
@ -728,11 +728,20 @@ public boolean contains(Object o) {
为了保证线程安全,`ArrayBlockingQueue` 的并发控制采用可重入锁 `ReentrantLock` ,不管是插入操作还是读取操作,都需要获取到锁才能进行操作。并且,它还支持公平和非公平两种方式的锁访问机制,默认是非公平锁。
`ArrayBlockingQueue` 虽名为阻塞队列,但也支持非阻塞获取和新增元素,只是队列满时添加元素会抛出异常,队列为空时获取的元素为 null。
`ArrayBlockingQueue` 虽名为阻塞队列,但也支持非阻塞获取和新增元素(例如 `poll()``offer(E e)` 方法),只是队列满时添加元素会抛出异常,队列为空时获取的元素为 null一般不会使用。
### ArrayBlockingQueue 和 LinkedBlockingQueue 有什么区别?
`ArrayBlockingQueue``LinkedBlockingQueue` 是 Java 并发包中常用的两种阻塞队列实现,它们都是线程安全的。不过,不过它们之间也存在下面这些区别:
- 底层实现:`ArrayBlockingQueue` 基于数组实现,而 `LinkedBlockingQueue` 基于链表实现。
- 是否有界:`ArrayBlockingQueue` 是有界队列,必须在创建时指定容量大小。`LinkedBlockingQueue` 创建时可以不指定容量大小,默认是`Integer.MAX_VALUE`,也就是无界的。但也可以指定队列大小,从而成为有界的。
- 锁是否分离: `ArrayBlockingQueue`中的锁是没有分离的,即生产和消费用的是同一个锁;`LinkedBlockingQueue`中的锁是分离的,即生产用的是`putLock`,消费是`takeLock`,这样可以防止生产者和消费者线程之间的锁争夺。
- 内存占用:`ArrayBlockingQueue` 需要提前分配数组内存,而 `LinkedBlockingQueue` 则是动态分配链表节点内存。这意味着,`ArrayBlockingQueue` 在创建时就会占用一定的内存空间,且往往申请的内存比实际所用的内存更大,而`LinkedBlockingQueue` 则是根据元素的增加而逐渐占用内存空间。
### ArrayBlockingQueue 和 ConcurrentLinkedQueue 有什么区别?
`ArrayBlockingQueue``ConcurrentLinkedQueue` 是 Java 并发包中常用的两种队列实现,它们都是线程安全的,可以在多线程环境下使用。不过,不过它们之间也存在一些区别的。
`ArrayBlockingQueue``ConcurrentLinkedQueue` 是 Java 并发包中常用的两种队列实现,它们都是线程安全的。不过,不过它们之间也存在下面这些区别:
- 底层实现:`ArrayBlockingQueue` 基于数组实现,而 `ConcurrentLinkedQueue` 基于链表实现。
- 是否有界:`ArrayBlockingQueue` 是有界队列,必须在创建时指定容量大小,而 `ConcurrentLinkedQueue` 是无界队列,可以动态地增加容量。

View File

@ -477,3 +477,12 @@ Java 中常用的阻塞队列实现类有以下几种:
6. ......
日常开发中,这些队列使用的其实都不多,了解即可。
### ArrayBlockingQueue 和 LinkedBlockingQueue 有什么区别?
`ArrayBlockingQueue``LinkedBlockingQueue` 是 Java 并发包中常用的两种阻塞队列实现,它们都是线程安全的。不过,不过它们之间也存在下面这些区别:
- 底层实现:`ArrayBlockingQueue` 基于数组实现,而 `LinkedBlockingQueue` 基于链表实现。
- 是否有界:`ArrayBlockingQueue` 是有界队列,必须在创建时指定容量大小。`LinkedBlockingQueue` 创建时可以不指定容量大小,默认是`Integer.MAX_VALUE`,也就是无界的。但也可以指定队列大小,从而成为有界的。
- 锁是否分离: `ArrayBlockingQueue`中的锁是没有分离的,即生产和消费用的是同一个锁;`LinkedBlockingQueue`中的锁是分离的,即生产用的是`putLock`,消费是`takeLock`,这样可以防止生产者和消费者线程之间的锁争夺。
- 内存占用:`ArrayBlockingQueue` 需要提前分配数组内存,而 `LinkedBlockingQueue` 则是动态分配链表节点内存。这意味着,`ArrayBlockingQueue` 在创建时就会占用一定的内存空间,且往往申请的内存比实际所用的内存更大,而`LinkedBlockingQueue` 则是根据元素的增加而逐渐占用内存空间。