gpt4 book ai didi

Java ArrayBlockingQueue 取源码

转载 作者:行者123 更新时间:2023-12-01 19:53:07 25 4
gpt4 key购买 nike

当我阅读ArrayBlockingQueue.take方法的源代码时,我遇到了一个问题。

我认为两个线程同时调用 take 方法,只有一个线程可以成功获取锁,而另一个线程将在以下行等待锁:lock.lockInterruptically();这是take的源代码:

public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0)
notEmpty.await();
return dequeue();
} finally {
lock.unlock();
}
}

但是当我对两个线程进行线程转储时,我发现两个线程都成功锁定,并且在线等待:notEmpty.await();(因为队列为空)这是线程转储:

"test-thread-18" #6357 daemon prio=5 os_prio=0 tid=0x00007f8f54543000 nid=0x58ef waiting on condition [0x00007f901bc70000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00007f93ae695410> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.ArrayBlockingQueue.take(ArrayBlockingQueue.java:403) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)

"test-thread-17" #6356 daemon prio=5 os_prio=0 tid=0x00007f8f54542000 nid=0x58ee waiting on condition [0x00007f901beb9000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00007f93ae695410> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.ArrayBlockingQueue.take(ArrayBlockingQueue.java:403) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)

那么,为什么两个不同的线程可以同时获得相同的锁呢?我的理解有什么问题吗?

最佳答案

同一时间只有一个线程可以持有ReentrantLock

notEmptyCondition对象,当前线程调用Condition.await()时会释放锁:

Causes the current thread to wait until it is signalled orinterrupted. The lock associated with this Condition is atomicallyreleased and the current thread becomes disabled for thread schedulingpurposes and lies dormant until one of four things happens:

  • Some other thread invokes the signal() method for this Condition andthe current thread happens to be chosen as the thread to be awakened;
  • or Some other thread invokes the signalAll() method for thisCondition;
  • or Some other thread interrupts the current thread, andinterruption of thread suspension is supported;-or A "spurious wakeup"occurs.

In all cases, before this method can return the current threadmust re-acquire the lock associated with this condition. When thethread returns it is guaranteed to hold this lock.

关于Java ArrayBlockingQueue 取源码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50596114/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com