Когда я читал исходный код метода ArrayBlockingQueue.take, у меня возникла проблема.
Я думаю, что тогда два потока вызывают метод take одновременно, только один поток мог успешно получить блокировку, а другой поток ожидална блокировку в строке: lock.lockInterruptibly();
это исходный код 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 демон prio = 5 os_prio = 0 tid = 0x00007f8f54543000 nid = 0x58ef, ожидающий наусловие [0x00007f901bc70000] java.lang.Thread.State: WAITING (парковка) на sun.misc.Unsafe.park (собственный метод) - парковка для ожидания <0x00007f93ae695410> (java.util.concurrent.locks.AbstractQueuedSject) $в java.util.concurrent.locks.LockSupport.park (LockSupport.java:175) в java.util.concurrent.locks.AbstractQueuedSynchronizer $ ConditionObject.await (AbstractQueuedSynchronizer.java:2039) в java.util.concurrent.ArrayBlockingQueue.take (ArrayBlockingQueue.java:403) в java.util.concurrent.ThreadPoolExecutor.getTask (ThreadPoolExecutor.java:1067) в java.utiler.con(ThreadPoolExecutor.java:1127) в java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:617) в java.lang.Thread.run (Thread.java:745)
"test-thread-17 "# 6356 демон prio = 5 os_prio = 0 tid = 0x00007f8f54542000 nid = 0x58ee ожидание при условии [0x00007f901beb9000] java.lang.Thread.State: WAITING (стоянка) на sun.misc.Unsafe.park (основной метод)стоянка для ожидания <0x00007f93ae695410> (java.util.concurrent.locks.AbstractQueuedSynchronizer $ ConditionObject) в java.util.concurrent.locks.LockSupport.park (LockSupport.java:175) в java.rentglox$ ConditionObject.await (AbstractQueuedSynchronizer.java:2039) в java.util.concurrent.ArrayBlockingQueue.take (ArrayBlockingQueue.java:403) в java.util.concurrent.ThreadPoolExecutor.getTask (ThreadPoolExecutor.java:1067) в java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1127) в java.util.concurrent.ThreadPoolExecutor: рабочий класс.lang.Thread.run (Thread.java:745)
Итак, почему два разных потока могут получить одну и ту же блокировку одновременно?Что не так с моим пониманием?