够物网站空间100m够不够,wordpress智能推送,绿色环保材料网站模板下载,室内设计专业就业方向顾名思义#xff0c;就是一种在对队列进行出队或者入队操作的时候会阻塞的队列。下面使用JDK17中的LinkedBlockingQuece进行简单的介绍。
LinkedBlockingQueue基本结构
LinkedBlockingQueue的主要结构以及构成的数据结构如下图所示。具体来说包括
存储元素的链表#xff0…顾名思义就是一种在对队列进行出队或者入队操作的时候会阻塞的队列。下面使用JDK17中的LinkedBlockingQuece进行简单的介绍。
LinkedBlockingQueue基本结构
LinkedBlockingQueue的主要结构以及构成的数据结构如下图所示。具体来说包括
存储元素的链表first指针指向队头last指针指向队尾。控制向队列中入队节点的可重入锁 putLock以及队列满时让生产者线程排队等待的 notFull 条件等待队列。控制向队列中出队节点的可重入锁 takeLock以及队列为空的时候让消费者排队的 notEmpty 条件等待队列。尝试入队操作的生产者线程。尝试出队操作的消费者线程。 接下来介绍LinkedBlockingQueue的几个基本操作。
入队操作
put(E) 将元素入队如果队列满了那么将操作线程放入等待队列notFull, 直到入队成功。offer(E) 将元素入队如果队列满了那么直接返回false入队失败。
出队操作
take() 将元素出队如果队列为空那么将操作线程放入等待队列notEmpty直到出队成功。poll() 将元素出队如果队列为空返回false出队失败。
put,offer以及 take,poll的操作之间的不同都是在队列不满足条件的时候是将其放入条件等待队列等待队列满足条件的时候唤醒还是直接返回false表示操作失败。
出队入队的基本操作
put(E e)
具体流程如下图所示这是一个线程安全的队列因为每次队队列的入队出队操作必须获取锁之后才会继续运行。生产者线程在获取了putLock后判断队列是否还会达到容量如果还有容量那么直接放入如果队列已满那么放入notFull等待队列中。因为生产者在队尾操作消费者在队头操作不会相互影响在新增节点的过程中可能会有节点出队。所以在放入元素后判断队列是否还有容量如果有就将notFull等待队列中的线程唤醒。在释放锁后判断在插入前队列是否为空如果为空说明可能有消费者线程在条件等待队列中等待获取元素那么就去唤醒notEmpty中的线程这些线程由于之前队列为空被放入条件等待队列等待。 public void put(E e) throws InterruptedException {if (e null) throw new NullPointerException();final int c;final NodeE node new NodeE(e);final ReentrantLock putLock this.putLock;final AtomicInteger count this.count;putLock.lockInterruptibly();try {/** Note that count is used in wait guard even though it is* not protected by lock. This works because count can* only decrease at this point (all other puts are shut* out by lock), and we (or some other waiting put) are* signalled if it ever changes from capacity. Similarly* for all other uses of count in other wait guards.*/while (count.get() capacity) {notFull.await();}enqueue(node);c count.getAndIncrement();if (c 1 capacity)notFull.signal();} finally {putLock.unlock();}if (c 0)signalNotEmpty();
}take()
take操作与put操作类似只不过操作的锁和等待队列恰好相反。 public E take() throws InterruptedException {final E x;final int c;final AtomicInteger count this.count;final ReentrantLock takeLock this.takeLock;takeLock.lockInterruptibly();try {while (count.get() 0) {notEmpty.await();}x dequeue();c count.getAndDecrement();if (c 1)notEmpty.signal();} finally {takeLock.unlock();}if (c capacity)signalNotFull();return x;}另外需要注意的是 使用的两个可重入锁为 非公平锁也就是说队列中的顺序并不严格满足先进先出的特性。源码的解释也有点冲突。