Java.util.concurrent包学习(一) BlockingQueue接口
JDK1.7
BlockingQueue<E>接口 (extends Queue<E>)
所有父接口:Collection<E>,Iterable<E>,Queue<E>
所有子接口:BlockingDeque<E>,TransferQueue<E>
所有实现该接口的类:ArrayBlockingQueue,DelayQueue,LinkedBlockingQueue,LinkedTransferQueue,PriorityBlockingQueue,SynchronousQueue,LinkedBlockingDeque
一种支持操作等待的队列,取元素时如果队列为空则等待队列变为非空,放元素时如果队列满则等待队列有可用空间。元素出入方式为FIFO。
BlockingQueue的方法有四种形式构成:见下表:
Throws exception | Special value | Blocks | Times out | |
Insert | add(e) | offer(e) | put(e) | offer(e,time,unit) |
Remove | remove() | poll() | take() | poll(time,unit) |
Examine | element() | peek() | not applicable | not applicable |
BlockingQueue不接受null值元素,通过add,offer,put方法试图添加null值会抛NullPointerException. 因为null值是用来指明poll方法失败的。
BlockingQueue有容量界限,任何时候都可以通过remainingCapacity值查看可用容量,当已用容量超过remainingCapacity值时,额外的元素不能无阻塞的添加到队列中。
没有内在容量限制的队列,remainingCapacity会返回Integer.MAX值。
BlockingQueue实现类设计初衷主要用于生产者-消费者队列,但是也支持了Collection接口,因此,可以使用remove(e)方法从队列中移除任何元素。但是需要注意的是,
这种操作并不高效,偶尔才使用到。
BlockingQueue实现类都是线程安全(Thread-safe)的,所有排队方法都通过内部锁或者其他并发控制实现了原子操作。但是,像集合堆的操作,addAll(),containsAll(),
retainAll(),removeAll(),实现类中没有特殊规定的话就没有必要实现原子操作,所以,当使用addAll(c)可能会存在添加一部分之后操作失败了。
代码示例,基于典型的生产者-消费者场景。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) { ...}
}
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) { ... }
}
void consume(Object x) { ... }
} public class Main{
public static void main(String[] args) {
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();
}
}
最新文章
- selenium元素定位篇
- python :表单验证--对每一个输入框进行验证
- Nginx负载均衡配置实例详解
- PHP简单图片操作
- android平台手电筒开发源代码
- Redis 网络通信及连接机制学习
- PHP安全之register_globals
- Mac下安装Mysql出现 Can’t connect to local MySQL server through socket &#39;/tmp/mysql.sock&#39;
- 集群下Cookie共享,必须要设置machineKey
- [NOIp 2009]Hankson的趣味题
- Redis+Django(Session,Cookie、Cache)的用户系统
- 学习ASP.NET Core Razor 编程系列十九——分页
- UVa10474
- vue 项目实战 (生命周期钩子)
- Resolve Missing artifact Issue in maven
- mui init 出现无法引入子页面问题
- JavaScript在页面中的引用方法
- 在eclipse中,用maven创建web项目
- HTTP状态码具体解释
- 003---生成器 &; 迭代器