java求生序列_Java 经典面试题:聊一聊 JUC 下的 LinkedBlockingQueue_绝地求生黑号,dnf辅助...

C# 基础知识系列- 17 小工具优化pubg卡盟

本文聊一下 JUC 下的 LinkedBlockingQueue 行列,先说说 LinkedBlockingQueue 行列的特点,然后再从源码的角度聊一聊 LinkedBlockingQueue 的主要实现~

LinkedBlockingQueue 有以下特点:

LinkedBlockingQueue 是壅闭行列,底层是单链表实现的~

元素从行列尾进队,从行列头出队,相符FIFO~

可以使用 Collection 和 Iterator 两个接口的所有操作,由于实现了两者的接口~

LinkedBlockingQueue 行列读写操作都加了锁,然则读写用的是两把差别的锁,以是可以同时读写操作~

LinkedBlockingQueue 行列继续了 AbstractQueue 类,实现了 BlockingQueue 接口,LinkedBlockingQueue 主要有以下接口:

//将指定的元素插入到此行列的尾部(若是立刻可行且不会跨越该行列的容量)

//在乐成时返回 true,若是此行列已满,则抛IllegalStateException。

boolean add(E e);

//将指定的元素插入到此行列的尾部(若是立刻可行且不会跨越该行列的容量)

// 将指定的元素插入此行列的尾部,若是该行列已满,

//则在到达指定的守候时间之前守候可用的空间,该方式可中止

boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException;

//将指定的元素插入此行列的尾部,若是该行列已满,则一直等到(壅闭)。

void put(E e) throws InterruptedException;

//获取并移除此行列的头部,若是没有元素则守候(壅闭),

//直到有元素将叫醒守候线程执行该操作

E take() throws InterruptedException;

//获取并移除此行列的头,若是此行列为空,则返回 null。

E poll();

//获取并移除此行列的头部,在指定的守候时间前一直等到获取元素, //跨越时间方式将竣事

E poll(long timeout, TimeUnit unit) throws InterruptedException;

//今后行列中移除指定元素的单个实例(若是存在)。

boolean remove(Object o);

//获取但不移除此行列的头元素,没有则跑异常NoSuchElementException

E element();

//获取但不移除此行列的头;若是此行列为空,则返回 null。

E peek();

LinkedBlockingQueue 行列的读写方式异常的多,然则常用的是 put()、take()方式,由于它们两是壅闭的,以是我们就从源码的角度来聊一聊 LinkedBlockingQueue 行列中这两个方式的实现。

先来看看 put()方式,源码如下:

public void put(E e) throws InterruptedException {

if (e == null) throw new NullPointerException();

// 预先设置 c 的值为 -1,示意失败

int c = -1;

Node node = new Node(e);

// 获取写锁

final ReentrantLock putLock = this.putLock;

// 获取当前行列的巨细

final AtomicInteger count = this.count;

// 设置可中止锁

putLock.lockInterruptibly();

try {

// 行列满了

// 当前线程壅闭,守候其他线程的叫醒(其他线程 take 乐成后就会叫醒此处线程)

while (count.get() == capacity) {

// 无限期守候

notFull.await();

}

// 新增到行列尾部

enqueue(node);

// 获取当前的行列数

c = count.getAndIncrement();

// 若是行列未满,实验叫醒一个put的守候线程

if (c 1 < capacity)

notFull.signal();

} finally {

// 释放锁

putLock.unlock();

}

if (c == 0)

signalNotEmpty();

}

put()方式的源码并不难,异常容易就看懂,put()方式的历程也许如下:,pubg辅助,

1、先加锁,保证容器的并发平安~

2、行列新增数据,将数据追加到行列尾部~

3、新增时,若是行列满了,当前线程是会被壅闭的,守候被叫醒~

4、新增数据乐成后,在适当时机,会唤起 put 的守候线程(行列不满时),或者 take 的守候线程(行列不为空时),这样保证行列一旦知足 put 或者 take 条件时,立马就能唤起壅闭线程,继续运行,保证了唤起的时机不被虚耗offer 就有两两种,一种是直接返回 false,另一种是跨越一定时间后返回 false~

5、释放锁~

其他的新增方式,例如 offer,可以查看源码,跟put() 方式大同小异,相差不大~

再来看看 take()方式,源码如下:

public E take() throws InterruptedException {

E x;

// 默认负数

int c = -1;

// 当前链表的个数

final AtomicInteger count = this.count;

//获取读锁

final ReentrantLock takeLock = this.takeLock;

takeLock.lockInterruptibly();

try {

// 当行列为空时,壅闭,守候其他线程叫醒

while (count.get() == 0) {

notEmpty.await();

}

// 从行列的头部拿出一个元素

x = dequeue();

//减一操作,C比真实的行列数据大一

c = count.getAndDecrement();

// c 大于 0 ,示意行列有值,可以叫醒之前被壅闭的读线程

if (c > 1)

notEmpty.signal();

} finally {

// 释放锁

takeLock.unlock();

}

// 行列未满,可以叫醒 put 守候线程~

if (c == capacity)

signalNotFull();

return x;

}

take()方式跟 put() 方式类似,是一个相反的操作,我就不做过多的说明晰~

以上就是 LinkedBlockingQueue 行列的简朴源码剖析,希望对你的面试或者事情有所辅助,谢谢你的阅读~

迎接关注民众号【互联网平头哥】,一起发展,一起提高~。

NBnyee.jpeg,彩虹六号辅助HTTP头部信息和错误代码详解-《HTTP权威指南》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值