简体   繁体   English

PriorityBlockingQueue中的锁定/解锁推理是什么?

[英]What could be the locking / unlocking reasoning in PriorityBlockingQueue?

I have been reading the source code of PriorityBlockingQueue in Java and I was wondering : 我一直在阅读Java 中PriorityBlockingQueue源代码,我想知道:

  1. why is the tryGrow() method releasing the lock acquired during the offer() method, just to do its thing non-blocking, and then block again when ready to replace the contents of the queue ? 为什么tryGrow()方法释放在offer()方法期间获取的锁,只是为了使其非阻塞性地工作,然后在准备替换队列内容时再次阻塞? i mean, it could have just kept the lock it had... 我的意思是,它本来可以保持它的锁...
  2. how come this works? 这怎么运作的? growing the queue, which involves an array copy, does not cause misbehavior on concurrent adds, where the additional adds can totally come when the current add is increasing the size of the queue? 增加涉及数组副本的队列不会导致并发添加时出现异常,当当前添加正在增加队列的大小时,完全可以出现附加添加?

Because the memory allocation can be comparatively slow and can be done while the array is unlocked. 因为内存分配可能相对较慢,并且可以在解锁数组时完成。

By releasing the lock it is allowing other threads to continue functioning while it is allocating the (potentially large) new array. 通过释放该锁,它允许其他线程在分配(可能很大)新数组时继续运行。

As this process can be done without locks it is good practice to do so. 由于此过程可以在没有锁的情况下进行,因此,这样做是一个好习惯。 You should only hold a lock for the minimum length of time that you have to. 您只应将锁保持在最短的时间长度内。

Sufficient checks are made to ensure no other thread is doing this at the same time. 进行了充分的检查,以确保没有其他线程同时在执行此操作。

UNSAFE.compareAndSwapInt(this, allocationSpinLockOffset, 0, 1)

will allow only one thread into this section of code at a time. 一次将只允许一个线程进入此代码段。

Note the 注意

lock.lock();
if (newArray != null && queue == array) {

This grabs the lock again and then confirms that the array it is about to replace is the same one it grabbed a copy of at the start. 这将再次获取该锁,然后确认要替换的阵列与开始时获取副本的阵列相同。 If it has been replaced meanwhile then it just abandons the one it has just created on the assumption that some other thread has grown the array. 如果同时对其进行了替换,则它会在假定其他线程已增长数组的前提下放弃刚刚创建的那个数组。

If it is still the same it then copies the old data into the new bigger array and plants it back into the field. 如果仍然相同,则将旧数据复制到更大的新阵列中,然后将其种植回现场。

As Kamil nicely explains. 正如卡米尔(Kamil)很好地解释的那样。

Purpose of that unlock is only to be sure that the faster thread will grow the queue, so we will not waste time while locking the "better ones". 解锁的目的只是为了确保更快的线程会增加队列,因此在锁定“更好的”线程时我们不会浪费时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM