如果我們看代碼here,我們可以看到在獲取元素之前必須先進行鎖定。如果有很多線程正在使用,那麼這個鎖會有爭用 - 線程不會等待某些內容出現,而是等待其他線程處理。
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;
}
編輯
在你有一個接受者和大量的推杆和隊列狀態越來越充分的瓶頸將成爲這段代碼
private void signalNotFull() {
final ReentrantLock putLock = this.putLock;
putLock.lock();
try {
notFull.signal();
} finally {
putLock.unlock();
}
}
這需要給出signalNotFull()
的情況下以putLock
來表示隊列中現在有空間的事實。
「把take()放到另一個線程中」是什麼意思?你能否給出一些代碼示例來顯示哪些線程在做什麼?整體表現或時間花在take()上的性能有所提高? – selig
不幸的是,它是不可能的代碼,因爲關於性能的流程是複雜的 – user2479100
,總體時間更好,因爲take()更好... – user2479100