JAVA阻塞队列BlockingQueue
来源:互联网 发布:手机钢琴软件下载 编辑:程序博客网 时间:2024/05/14 16:43
原文:http://blog.csdn.net/ghsau/article/details/8108292
BlockingQueue最终会有四种状况,抛出异常、返回特殊值、阻塞、超时,下表总结了这些方法:
抛出异常特殊值阻塞超时插入add(e)
offer(e)
put(e)
offer(e, time, unit)
移除remove()
poll()
take()
poll(time, unit)
检查element()
peek()
不可用不可用
BlockingQueue是个接口,有如下实现类:
1. ArrayBlockQueue:一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。创建其对象必须明确大小,像数组一样。
2. LinkedBlockQueue:一个可改变大小的阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。创建其对象如果没有明确大小,默认值是Integer.MAX_VALUE。链接队列的吞吐量通常要高于基于数组的队列,但是在大多数并发应用程序中,其可预知的性能要低。
3. PriorityBlockingQueue:类似于LinkedBlockingQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数所带的Comparator决定的顺序。
4. SynchronousQueue:同步队列。同步队列没有任何容量,每个插入必须等待另一个线程移除,反之亦然。
下面使用ArrayBlockQueue来实现放鸡蛋和取鸡蛋的生产者消/费者模式,代码如下:
/** 定义一个盘子类,可以放鸡蛋和取鸡蛋 */ public class BigPlate { /** 装鸡蛋的盘子,大小为5 */ private BlockingQueue<Object> eggs = new ArrayBlockingQueue<Object>(5); /** 放鸡蛋 */ public void putEgg(Object egg) { try { eggs.put(egg);// 向盘子末尾放一个鸡蛋,如果盘子满了,当前线程阻塞 } catch (InterruptedException e) { e.printStackTrace(); } // 下面输出有时不准确,因为与put操作不是一个原子操作 System.out.println("放入鸡蛋"); } /** 取鸡蛋 */ public Object getEgg() { Object egg = null; try { egg = eggs.take();// 从盘子开始取一个鸡蛋,如果盘子空了,当前线程阻塞 } catch (InterruptedException e) { e.printStackTrace(); } // 下面输出有时不准确,因为与take操作不是一个原子操作 System.out.println("拿到鸡蛋"); return egg; } /** 放鸡蛋线程 */ static class AddThread extends Thread { private BigPlate plate; private Object egg = new Object(); public AddThread(BigPlate plate) { this.plate = plate; } public void run() { plate.putEgg(egg); } } /** 取鸡蛋线程 */ static class GetThread extends Thread { private BigPlate plate; public GetThread(BigPlate plate) { this.plate = plate; } public void run() { plate.getEgg(); } } public static void main(String[] args) { BigPlate plate = new BigPlate(); // 先启动10个放鸡蛋线程 for(int i = 0; i < 10; i++) { new Thread(new AddThread(plate)).start(); } // 再启动10个取鸡蛋线程 for(int i = 0; i < 10; i++) { new Thread(new GetThread(plate)).start(); } } }
执行结果:
放入鸡蛋 放入鸡蛋 放入鸡蛋 放入鸡蛋 放入鸡蛋 拿到鸡蛋 放入鸡蛋 拿到鸡蛋 拿到鸡蛋 拿到鸡蛋 放入鸡蛋 放入鸡蛋 放入鸡蛋 拿到鸡蛋 放入鸡蛋 拿到鸡蛋 拿到鸡蛋 拿到鸡蛋 拿到鸡蛋 拿到鸡蛋
从结果看,启动10个放鸡蛋线程和10个取鸡蛋线程,前5个放入鸡蛋的线程成功执行,到第6个,发现盘子满了,阻塞住,这时切换到取鸡蛋线程执行,成功实现了生产者/消费者模式,java.util.concurrent包是个强大的包!。线程池中,也使用了阻塞队列,可以参看线程池的源码。
- Java 阻塞队列 BlockingQueue
- java 阻塞队列BlockingQueue
- Java : BlockingQueue 阻塞队列
- JAVA阻塞队列BlockingQueue
- Java多线程-阻塞队列BlockingQueue
- Java线程:阻塞队列BlockingQueue
- BlockingQueue 阻塞队列 -- Java 多线程
- java中的阻塞队列BlockingQueue
- java多线程-BlockingQueue(阻塞队列)
- Java多线程-BlockingQueue(阻塞队列)
- java中的阻塞队列BlockingQueue
- Java阻塞队列之BlockingQueue
- 理解java阻塞队列BlockingQueue
- Java中的阻塞队列BlockingQueue
- java的阻塞队列blockingqueue
- Java线程(篇外篇):阻塞队列BlockingQueue
- java阻塞队列BlockingQueue使用实例
- Java线程(七):阻塞队列BlockingQueue
- 中断机制和中断描述符表、中断和异常的处理
- 验证码倒计时
- 343. Integer Break
- Win7下Qt 5 + OpenCV 2.4.13配置
- 框架测试
- JAVA阻塞队列BlockingQueue
- eclipse隐藏jar设置
- 双向广搜 代码框架
- 优秀程序设计的Kiss原则(keep it simple,stupid)
- hduoj1593
- 选股策略二:用pandas pd.merge()进行类海龟法则选股
- 3-2MR第一个例子(Hadoop系列day03)
- jquery即点即改
- Jquery选择器和选取方法