????????? BlockingQueue ?????????????
????1??add????????????????????????true???????????????????????? IllegalStateException ????
????2??offer????????????????????????true???????????false??
????3??put????????????????????????????????????????????
????4??poll???????????????????????????????null????????????
????5??remove??????????????????????????????????????true????????false??
????6??take??????????????????????????????????????????????????
?????????????? ArrayBlockingQueue ?? ArrayBlockingQueue???????????????????????????????????????????????в???????(classic two-condition algorithm) ??
????ArrayBlockingQueue
????ArrayBlockingQueue????????г???????????У?????????????????????г???????????????????????????
???????????£?
/** The queued items item????? */
final Object[] items;
/** items index for next take?? poll?? peek or remove ???????????? */
int takeIndex;
/** items index for next put?? offer?? or add ??????????? */
int putIndex;
/** Number of elements in the queue ??????????? */
int count;
/** Main lock guarding all access ????????? */
final ReentrantLock lock;
/** Condition for waiting takes ???????? */
private final Condition notEmpty;
/** Condition for waiting puts ???????? */
private final Condition notFull;
??????????add??????
public boolean add(E e) {
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");
}
offer??????
public boolean offer(E e) {
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (count == items.length)
return false;
else {
insert(e);
return true;
}
} finally {
lock.unlock();
}
}
??????????????????????????false??????????????insert????????????????????????????????????????????????? insert ??????
????private void insert(E x) {
????items[putIndex] = x; // ?????????????
????putIndex = inc(putIndex); // ??????????+1??????????????0
????++count; // ??????+1
????notEmpty.signal(); // ???????????notEmpty??
????}
???????? insert ????????????? notEmpty ????????????? take ??????
?????????? put ??????
public void put(E e) throws InterruptedException {
checkNotNull(e); // ????????????
final ReentrantLock lock = this.lock;
lock.lockInterruptibly(); // ?????????????put????????????1?????
try {
while (count == items.length) // ???????????????????????while????????????
notFull.await(); // ??????????????????????
insert(e); // ????insert????
} finally {
lock.unlock(); // ??????????????????????put????
}
}
????add??????offer????????????????put??????????????????????????????????????????????????п?????????
????????????????????????????????poll??
public E poll() {
final ReentrantLock lock = this.lock;
lock.lock(); // ?????????????poll????????????1?????
try {
return (count == 0) ? null : extract(); // ????????????????????null?????????extract????
} finally {
lock.unlock(); // ??????????????????????poll????
}
}
??????????? extract ??????jdk???????????????????????????????????
private E extract() {
final Object[] items = this.items;
E x = this.<E>cast(items[takeIndex]); // ????????λ????????
items[takeIndex] = null; // ??????????????????
takeIndex = inc(takeIndex); // ?????????+1??????????????0
--count; // ??????-1
notFull.signal(); // ???????????notFull?????????????insert??
return x; // ???????
}
????????? take ??????
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly(); // ?????????????take????????????1?????
try {
while (count == 0) // ??????п???????????????????????????notEmpty??????????
notEmpty.await(); // ??????????????????????
return extract(); // ????extract????
} finally {
lock.unlock(); // ??????????????????????take????
}
}
?????????? remove ??????
public boolean remove(Object o) {
if (o == null) return false;
final Object[] items = this.items;
final ReentrantLock lock = this.lock;
lock.lock(); // ?????????????remove????????????1?????
try {
for (int i = takeIndex?? k = count; k > 0; i = inc(i)?? k--) { // ???????
if (o.equals(items[i])) { // ?????????????
removeAt(i); // ????removeAt????
return true; // ????????????true
}
}
return false; // ????????????false
} finally {
lock.unlock(); // ??????????????????????remove????
}
}
?????????? removeAt ?????????????????????м????
private void removeAt(int i) {
final Object[] items = this.items;
if (i == takeIndex) {
// ???????????????????????λ??????????????λ??????????????????+1????
items[takeIndex] = null;
takeIndex = inc(takeIndex);
} else {
// ?????????????????????????λ????????????????????????????????
for (;;) {
int nexti = inc(i);
if (nexti != putIndex) {
items[i] = items[nexti];
i = nexti;
} else {
items[i] = null;
putIndex = i;
break;
}
}
}
--count; // ??????-1
notFull.signal(); // ???????????notFull??
}