package com.itsoku.lesson009.comm;
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
/**
* <b>description</b>: 支持扩容的阻塞队列 <br>
* <b>time</b>:2024/4/2 23:39 <br>
* <b>author</b>:ready
*/
public class ResizeLinkedBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable {
private static final long serialVersionUID = -6903933977591709194L;
/*
* A variant of the "two lock queue" algorithm. The putLock gates
* entry to put (and offer), and has an associated condition for
* waiting puts. Similarly for the takeLock. The "count" field
* that they both rely on is maintained as an atomic to avoid
* needing to get both locks in most cases. Also, to minimize need
* for puts to get takeLock and vice-versa, cascading notifies are
* used. When a put notices that it has enabled at least one take,
* it signals taker. That taker in turn signals others if more
* items have been entered since the signal. And symmetrically for
* takes signalling puts. Operations such as remove(Object) and
* iterators acquire both locks.
*
* Visibility between writers and readers is provided as follows:
*
* Whenever an element is enqueued, the putLock is acquired and
* count updated. A subsequent reader guarantees visibility to the
* enqueued Node by either acquiring the putLock (via fullyLock)
* or by acquiring the takeLock, and then reading n = count.get();
* this gives visibility to the first n items.
*
* To implement weakly consistent iterators, it appears we need to
* keep all Nodes GC-reachable from a predecessor dequeued Node.
* That would cause two problems:
* - allow a rogue Iterator to cause unbounded memory retention
* - cause cross-generational linking of old Nodes to new Nodes if
* a Node was tenured while live, which generational GCs have a
* hard time dealing with, causing repeated major collections.
* However, only non-deleted Nodes need to be reachable from
* dequeued Nodes, and reachability does not necessarily have to
* be of the kind understood by the GC. We use the trick of
* linking a Node that has just been dequeued to itself. Such a
* self-link implicitly means to advance to head.next.
*/
/**
* Linked list node class
*/
static class Node<E> {
E item;
/**
* One of:
* - the real successor Node
* - this Node, meaning the successor is head.next
* - null, meaning there is no successor (this is the last node)
*/
ResizeLinkedBlockingQueue.Node<E> next;
Node(E x) {
item = x;
}
}
/**
* The capacity bound, or Integer.MAX_VALUE if none
*/
private int capacity;
/**
* Current number of elements
*/
private final AtomicInteger count = new AtomicInteger();
/**
* Head of linked list.
* Invariant: head.item == null
*/
transient ResizeLinkedBlockingQueue.Node<E> head;
/**
* Tail of linked list.
* Invariant: last.next == null
*/
private transient ResizeLinkedBlockingQueue.Node<E> last;
/**
* Lock held by take, poll, etc
*/
private final ReentrantLock takeLock = new ReentrantLock();
/**
* Wait queue for waiting takes
*/
private final Condition notEmpty = takeLock.newCondition();
/**
* Lock held by put, offer, etc
*/
private final ReentrantLock putLock = new ReentrantLock();
/**
* Wait queue for waiting puts
*/
private final Condition notFull = putLock.newCondition();
/**
* Signals a waiting take. Called only from put/offer (which do not
* otherwise ordinarily lock takeLock.)
*/
private void signalNotEmpty() {
final ReentrantLock takeLock = this.takeLock;
takeLock.lock();
try {
notEmpty.signal();
} finally {
takeLock.unlock();
}
}
/**
* Signals a waiting put. Called only from take/poll.
*/
private void signalNotFull() {
final ReentrantLock putLock = this.putLock;
putLock.lock();
try {
notFull.signal();
} finally {
putLock.unlock();
}
}
/**
* Links node at end of queue.
*
* @param node the node
*/
private void enqueue(ResizeLinkedBlockingQueue.Node<E> node) {
// assert putLock.isHeldByCurrentThread();
// assert last.next == null;
last = last.next = node;
}
/**
* Removes a node from head of queue.
*
* @return the node
*/
private E dequeue() {
// assert takeLock.isHeldByCurrentThread();
// assert head.item == null;
ResizeLinkedBlockingQueue.Node<E> h = head;
ResizeLinkedBlockingQueue.Node<E> first = h.next;
h.next = h; // help GC
head = first;
E x = first.item;
first.item = null;
return x;
}
/**
* Locks to prevent both puts and takes.
*/
void fullyLock() {
putLock.lock();
takeLock.lock();
}
/**
* Unlocks to allow both puts and takes.
*/
void fullyUnlock() {
takeLock.unlock();
putLock.unlock();
}
// /**
// * Tells whether both locks are held by current thread.
// */
// boolean isFullyLocked() {
// return (putLock.isHeldByCurrentThread() &&
// takeLock.isHeldByCurrentThread());
// }
/**
* Creates a {@code ResizeLinkedBlockingQueue} with a capacity of
* {@link Integer#MAX_VALUE}.
*/
public ResizeLinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
/**
* Creates a {@code ResizeLinkedBlockingQueue} with the given (fixed) capacity.
*
* @param capacity the capacity of this queue
* @throws IllegalArgumentException if {@code capacity} is not greater
* than zero
*/
public ResizeLinkedBlockingQueue(int capacity) {
if (capacity <= 0) throw new IllegalArgumentException();
this.capacity = capacity;
last = head = new ResizeLinkedBlockingQueue.Node<E>(null);
}
/**
* Creates a {@code ResizeLinkedBlockingQueue} with a capacity of
* {@link Integer#MAX_VALUE}, initially containing the elements of the
* given collection,
* added in traversal order of the collection's iterator.
*
* @param c the collection of elements to initially contain
* @throws NullPointerException if the specified collection or any
* of its elements are null
*/
public ResizeLinkedBlockingQueue(Collection<? extends E> c) {
this(Integer.MAX_VALUE);
final ReentrantLock putLock = this.putLock;
putLock.lock(); // Never contended, but necessary for visibility
try {
int n = 0;
for (E e : c) {
if (e == null)
throw new NullPointerException();
if (n == capacity)
throw new IllegalStateException("Queue full");
enqueue(new ResizeLinkedBlockingQueue.Node<E>(e));
++n;
}
count.set(n);
} finally {
putLock.unlock();
}
}
/**
* 设置容量
* @param capacity
*/
public void setCapacity(int capacity) {
if (capacity <= 0) throw new IllegalArgumentException();
final ReentrantLock putLock = this.putLock;
putLock.lock();
try {
if (count.get() > capacity) {
throw new IllegalArgumentExcepti
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
springboot动态线程池.zip (31个子文件)
lesson009
pom.xml 3KB
src
test
resources
ThreadPoolManagerController.http 471B
main
resources
logback.xml 382B
java
com
itsoku
lesson009
Lesson009Application.java 524B
controller
ThreadPoolManagerController.java 973B
utils
TaskDisposeUtils.java 2KB
service
EmailSendService.java 3KB
comm
ThreadPoolChange.java 1KB
Result.java 386B
ThreadPoolManager.java 8KB
ThreadPoolInfo.java 1KB
ResizeLinkedBlockingQueue.java 33KB
ResultUtils.java 754B
config
ThreadPoolConfiguration.java 960B
target
classes
logback.xml 382B
com
itsoku
lesson009
Lesson009Application.class 756B
controller
ThreadPoolManagerController.class 2KB
utils
TaskDisposeUtils.class 4KB
service
EmailSendService.class 5KB
comm
Result.class 3KB
ThreadPoolManager$1.class 2KB
ThreadPoolManager.class 6KB
ThreadPoolInfo.class 2KB
ResizeLinkedBlockingQueue$LBQSpliterator.class 4KB
ResultUtils.class 2KB
ResizeLinkedBlockingQueue$Node.class 820B
ThreadPoolChange.class 1KB
ResizeLinkedBlockingQueue$Itr.class 3KB
ResizeLinkedBlockingQueue.class 13KB
config
ThreadPoolConfiguration.class 1KB
test-classes
ThreadPoolManagerController.http 471B
generated-sources
annotations
共 31 条
- 1
资源评论
蔡定努
- 粉丝: 1w+
- 资源: 64
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- FPGA市场和开发资源相关的视频
- LCD.ioc有关spi通信的
- 【Unity顶点纹理烘焙插件】Vertex Texture Baker
- Electric racing.zip
- 基于gurobi求解配电网网络重构的混合整数线性规划模型源码.zip
- **知识领域**:电子与通信技术 **技术关键词**:STM32F4开发板
- 【Unity塔防游戏素材包】Tower Defense Pack - Low Poly 3D Art
- 知识领域:电子与通信技术 技术关键词:激光测距、串口传输、STM32F4开发板 内容关键词:轮趣科技、激光测距模块、数据采
- Selenium的基本使用方法.pdf
- K210 实现PID算法的库文件
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功