当前位置: 首页>后端>正文

PriorityBlockingQueue 实现原理

PriorityBlockingQueue是线程安全的,之前我们看过priorityqueue的实现原理,https://www.jianshu.com/p/b0a2615f1bba?v=1672747035605

今天我们看一下PriorityBlockingQueue怎么实现线程安全的

PriorityBlockingQueue 实现原理,第1张

有个类的全局变量retrantlock。是在PriorityBlockingQueue的构造方法里面新建的。

PriorityBlockingQueue 实现原理,第2张

offer方法里面使用了retrantlock锁处理保证线程安全

在offer元素过程中可能需要扩容

扩容代码实现

private void tryGrow(Object[] array, int oldCap) {

lock.unlock(); // must release and then re-acquire main lock。//注释一?释放全局锁

? ? Object[] newArray =null;

if (allocationSpinLock ==0 &&UNSAFE.compareAndSwapInt(this, allocationSpinLockOffset,?0, 1)) {//注释二

try {

int newCap = oldCap + ((oldCap <64)

(oldCap +2) :// grow faster if small

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (oldCap >>1));

? ? ? ? ? ? if (newCap -MAX_ARRAY_SIZE >0) {// possible overflow

? ? ? ? ? ? ? ? int minCap = oldCap +1;

? ? ? ? ? ? ? ? if (minCap <0 || minCap >MAX_ARRAY_SIZE)

throw new OutOfMemoryError();

? ? ? ? ? ? ? ? newCap =MAX_ARRAY_SIZE;

? ? ? ? ? ? }

if (newCap > oldCap &&queue == array)

newArray =new Object[newCap];

? ? ? ? }finally {

allocationSpinLock =0;

? ? ? ? }

}if (newArray ==null)// back off if another thread is allocating

? ? ? ? Thread.yield();

? ? lock.lock(); //注释三

? ? if (newArray !=null &&queue == array) {

? ? ?queue = newArray;

? ? ? ? System.arraycopy(array, 0, newArray, 0, oldCap);??

? }}

入队时如何保证线程安全和效率

1.offer方法里面获取了自旋锁,保证了只有一个线程进行添加操作。

2.扩容方法(注释一?)会释放锁。这样保证offer方法可以进行入队操作

3.注释二? cas操作保证只有一个线程进行扩容

4.然后获取锁进行数据拷贝到扩容后的数组,因为这个操作会随着数据的增长耗费些时间。

所以采用了加锁操作。其他线程会进行yield然后进行自旋。

出队时用的就是加锁来实现的


https://www.xamrdz.com/backend/3hp1924787.html

相关文章: