如果我们查看这里的代码,我们可以看到在获取元素之前必须获取锁。如果有很多线程正在占用,那么这个锁就会发生争用——线程不是在等待某些东西出现,而是在等待其他线程来占用。
public E take() throws InterruptedException {
E x;
int c = -1;
final AtomicInteger count = this.count;
final ReentrantLock takeLock = this.takeLock;
takeLock.lockInterruptibly();
try {
try {
while (count.get() == 0)
notEmpty.await();
} catch (InterruptedException ie) {
notEmpty.signal(); // propagate to a non-interrupted thread
throw ie;
}
x = extract();
c = count.getAndDecrement();
if (c > 1)
notEmpty.signal();
} finally {
takeLock.unlock();
}
if (c == capacity)
signalNotFull();
return x;
}
编辑
如果您有一个接受者和很多推杆并且队列不断满员,则signalNotFull()
此代码将给出瓶颈
private void signalNotFull() {
final ReentrantLock putLock = this.putLock;
putLock.lock();
try {
notFull.signal();
} finally {
putLock.unlock();
}
}
这需要用 来putLock
表示队列中现在有空间的事实。