Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ArrayBlockingQueue获取源代码_Java_Multithreading_Concurrency_Locking - Fatal编程技术网

Java ArrayBlockingQueue获取源代码

Java ArrayBlockingQueue获取源代码,java,multithreading,concurrency,locking,Java,Multithreading,Concurrency,Locking,当我阅读ArrayBlockingQueue.take方法的源代码时,我遇到了一个问题 我认为两个线程同时调用take方法,只有一个线程可以成功地获得锁,而另一个线程将在以下行等待锁:lock.lockInterruptablely() 这是take的源代码: public E take() throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly();

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

我认为两个线程同时调用take方法,只有一个线程可以成功地获得锁,而另一个线程将在以下行等待锁:
lock.lockInterruptablely()
这是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=0x00007f8f5443000 nid=0x58ef等待条件[0x00007f901bc70000] java.lang.Thread.State:等待(停车) 在sun.misc.Unsafe.park(本机方法) -停车等待(java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) 位于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.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) 位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 运行(Thread.java:745)

“测试线程-17”#6356守护进程优先级=5 os_优先级=0 tid=0x00007F8F5442000 nid=0x58ee等待条件[0x00007f901beb9000] java.lang.Thread.State:等待(停车) 在sun.misc.Unsafe.park(本机方法) -停车等待(java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) 位于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.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) 位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 运行(Thread.java:745)

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

只有一个线程可以同时持有
可重入锁

notEmpty
是一个对象,当前线程将在调用时释放锁:

使当前线程等待,直到发出信号或 打断。与此条件相关的锁在原子上为 已释放,当前线程将被禁用以进行线程调度 在以下四种情况之一发生之前,目标和状态处于休眠状态:

  • 其他一些线程为此条件调用signal()方法,并 当前线程恰好被选为要唤醒的线程
  • 或者其他线程为此调用signalAll()方法 条件
  • 或者其他线程中断当前线程,并且 支持中断挂线; -还是“虚假的觉醒” 发生
在所有情况下,在该方法返回当前线程之前 必须重新获取与此条件相关的锁。当 线程返回并保证持有此锁


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

notEmpty
是一个对象,当前线程将在调用时释放锁:

使当前线程等待,直到发出信号或 打断。与此条件相关的锁在原子上为 已释放,当前线程将被禁用以进行线程调度 在以下四种情况之一发生之前,目标和状态处于休眠状态:

  • 其他一些线程为此条件调用signal()方法,并 当前线程恰好被选为要唤醒的线程
  • 或者其他线程为此调用signalAll()方法 条件
  • 或者其他线程中断当前线程,并且 支持中断挂线; -还是“虚假的觉醒” 发生
在所有情况下,在该方法返回当前线程之前 必须重新获取与此条件相关的锁。当 线程返回并保证持有此锁


您应该明确指出,
notEmpty
绑定到
lock
,因为这在问题中的代码中并不明显。谢谢。您指出了这个条件。wait()将释放锁,而a以前不知道。有了这些知识,我可以理解问题所在。您应该明确指出,
notEmpty
lock
绑定,因为这在问题中的代码中并不明显。谢谢。您指出了条件。await()将释放锁,这是a以前不知道的。有了这些知识,我就能理解问题所在。