BlockingQueue 是新增的Concurrent包中的一种阻塞队列
当BlockingQueue为空, 从队列取数据时会让线程等待状态,直到能取出非空的数据,线程会被唤醒。
当BlockingQueue是满的,存数据到队列时线程也会进入等待状态,直到有空间,线程才会被唤醒。
A Queue that additionally supports operations that wait for the queue to become non-empty when retrieving an element, and wait for space to become available in the queue when storing an element.
通过安全的BlockingQueue队列,能够很好的解决在多线程中,高效,安全的传输数据的问题,让我们能够快速的实现多线程操作,而不需关心一些线程安全的细节。
比如在典型的生产者消费者模式中,BlockingQueue 能够安全的应用在多个生产者,消费者线程中:
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... handle ...}
}
Object produce() { ... }
}
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... handle ...}
}
void consume(Object x) { ... }
}
class Setup {
void main() {
BlockingQueue q = new SomeQueueImplementation();
Producer p = new Producer(q);
Consumer c1 = new Consumer(q);
Consumer c2 = new Consumer(q);
new Thread(p).start();
new Thread(c1).start();
new Thread(c2).start();
}
}}
在多线程环境下,BlockingQueue能够处理线程间安全问题。
在BlockingQueue队列为空的时候,消费者端的所有线程会自动处于等待(挂起)状态,直到有数据放入队列。
当BlockingQueue队列已满的时候,生产者端的线程都会被挂起,直到队列有空间,生产者线程会自动被唤醒。
所以在多线程环境下,BlockingQueue能够自动挂起和唤醒线程,不需要关心阻塞和唤醒的问题,所有的事情BlockingQueue已经帮我们处理了,我们只需要知道如何使用它。
BlockingQueue 的方法有以下四种形式:
1.trows exception
将非空元素加入队列中,如果能够容纳,返回true,否则trows exception
移除队列头部元素,如果队列为空,trows exception
取出队列头部元素,如果队列为空,trows exception
2.返回值
将非空元素加入队列中,如果BlockingQueue可以容纳,则返回true,否则返回false.
移除队列头部元素,如果队列为空,返回null
取出队列头部元素,如果队列为空,返回null
3.blocks
添加元素到队列,如果队列已满,线程进入等待,直到有空间
移除队列头部元素,如果队列为空,线程进入等待,直到有新的数据加入
4.Times Out
移除队列头部元素,在等待的时间内如果队列为空,返回null
将非空元素加入队列中,在等待的时间内如果可以容纳,返回true,否则返回false