put方法:
public void put(E e) throws InterruptedException {
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == items.length)
notFull.await();
enqueue(e);
} finally {
lock.unlock();
}
}
take 方法:
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0)
notEmpty.await();
return dequeue();
} finally {
lock.unlock();
}
}
以上的put和take方法都有如下代码,而且这2个方法都是在类ArrayBlockingQueue中,所以他们都用的同一把锁。不管是take还是put方法想要往阻塞度列里面取、放元素都必须先拿到锁。也就是说同一时间只能对ArrayBlockingQueue有一个操作,要么take要么put,不能即在put有在take。
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
一旦同时有多个线程都想来操作ArrayBlockingQueue的时候,就会把他们的线程都放在一个双向队列(CLH),详细的解释请看对ReentrantLock源码分析的那个章节中。这里简单的解释就是同一时间只能有一个线程能操作ArrayBlockingQueue,其他的线程全部放在这个CLH 队列中,等当前操作完成,在让CLH