方法功能表
功能 | 抛出异常 | 返回特殊值 | 超时 | 阻塞 |
---|---|---|---|---|
新增 | add(e) | offer() | offer(timeout) | put(e) |
删除 | remove() | poll() | poll(timeout) | take() |
查询 | element() | peek() | 无 | 无 |
这些方法都使用了 ReentrantLock,所以BlockingQueue是线程安全的( add()方法不是 )
利用方法的阻塞性,可以很方便的实现生产者—消费者
说明:
1、offer() 增加元素,有可用的空间,返回true,否通返回false
public boolean offer(E e) {
Objects.requireNonNull(e);
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (count == items.length)
return false;
else {
enqueue(e);
return true;
}
} finally {
lock.unlock();
}
}
2、put 添加元素,没有可用的空间是,添加的线程一直等待(阻塞),直到有空余的空间,或者程序异常
public void put(E e) throws InterruptedException {
Objects.requireNonNull(e);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == items.length)
notFull.await();
enqueue(e);
} finally {
lock.unlock();
}
}
3.take() 返回并删除队列的头元素,也是一个阻塞的方法
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0)
notEmpty.await();
return dequeue();
} finally {
lock.unlock();
}
}
4、 add方法 不是线程安全 的
public boolean add(E e) {
return super.add(e); //调用的是AbstractQueue的方法,
}
?(上面调用下面)
AbstractQueue的方法
public boolean add(E e) {
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");
}