使用Java的BlockingQueue实现生产者-消费者
http://tonl.iteye.com/blog/1936391
使用Java的BlockingQueue实现生产者-消费者
BlockingQueue也是java.util.concurrent下的主要用来控制线程同步的工具。
BlockingQueue有四个具体的实现类,根据不同需求,选择不同的实现类
1、ArrayBlockingQueue:一个由数组支持的有界阻塞队列,规定大小的BlockingQueue,其构造函数必须带一个int参数来指明其大小.其所含的对象是以FIFO(先入先出)顺序排序的。
2、LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带一个规定大小的参数,生成的BlockingQueue有大小限制,若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定.其所含的对象是以FIFO(先入先出)顺序排序的。
3、PriorityBlockingQueue:类似于LinkedBlockQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数的Comparator决定的顺序。
4、SynchronousQueue:特殊的BlockingQueue,对其的操作必须是放和取交替完成的。
LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的话,默认最大是Integer.MAX_VALUE,其中主要用到put和take方法,put方法在队列满的时候会阻塞直到有队列成员被消费,take方法在队列空的时候会阻塞,直到有队列成员被放进来。
生产者消费者的示例代码:
生产者:
- import java.util.concurrent.BlockingQueue;
- public class Producer implements Runnable {
- BlockingQueue<String> queue;
- public Producer(BlockingQueue<String> queue) {
- this.queue = queue;
- }
- @Override
- public void run() {
- try {
- String temp = "A Product, 生产线程:"
- + Thread.currentThread().getName();
- System.out.println("I have made a product:"
- + Thread.currentThread().getName());
- queue.put(temp);//如果队列是满的话,会阻塞当前线程
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
消费者:
- import java.util.concurrent.BlockingQueue;
- public class Consumer implements Runnable{
- BlockingQueue<String> queue;
- public Consumer(BlockingQueue<String> queue){
- this.queue = queue;
- }
- @Override
- public void run() {
- try {
- String temp = queue.take();//如果队列为空,会阻塞当前线程
- System.out.println(temp);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
测试类:
- import java.util.concurrent.ArrayBlockingQueue;
- import java.util.concurrent.BlockingQueue;
- import java.util.concurrent.LinkedBlockingQueue;
- public class Test3 {
- public static void main(String[] args) {
- BlockingQueue<String> queue = new LinkedBlockingQueue<String>(2);
- // BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
- //不设置的话,LinkedBlockingQueue默认大小为Integer.MAX_VALUE
- // BlockingQueue<String> queue = new ArrayBlockingQueue<String>(2);
- Consumer consumer = new Consumer(queue);
- Producer producer = new Producer(queue);
- for (int i = 0; i < 5; i++) {
- new Thread(producer, "Producer" + (i + 1)).start();
- new Thread(consumer, "Consumer" + (i + 1)).start();
- }
- }
- }
打印结果:
- I have made a product:Producer1
- I have made a product:Producer2
- A Product, 生产线程:Producer1
- A Product, 生产线程:Producer2
- I have made a product:Producer3
- A Product, 生产线程:Producer3
- I have made a product:Producer5
- I have made a product:Producer4
- A Product, 生产线程:Producer5
- A Product, 生产线程:Producer4
由于队列的大小限定成了2,所以最多只有两个产品被加入到队列当中,而且消费者取到产品的顺序也是按照生产的先后顺序,原因就是LinkedBlockingQueue和ArrayBlockingQueue都是按照FIFO的顺序存取元素的。
使用Java的BlockingQueue实现生产者-消费者的更多相关文章
- Java多线程15:Queue、BlockingQueue以及利用BlockingQueue实现生产者/消费者模型
Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移 ...
- Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例
Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java.util.concurr ...
- Java多线程(十):BlockingQueue实现生产者消费者模型
BlockingQueue BlockingQueue.解决了多线程中,如何高效安全"传输"数据的问题.程序员无需关心什么时候阻塞线程,什么时候唤醒线程,该唤醒哪个线程. 方法介绍 ...
- 使用BlockingQueue的生产者消费者模式
BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利.使用场景. 首先它是一个队列,而一个队 ...
- Queue和BlockingQueue的使用以及使用BlockingQueue实现生产者-消费者
Java提供了两种新的容器类型:Queue和BlockingQueue. Queue用于保存一组等待处理的元素.它提供了几种实现,包括:ConcurrentLinkedQueue,这是一个先进先出的并 ...
- Java多线程-并发协作(生产者消费者模型)
对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的.就像学习每一门编程语言一样,Hello World!都是最经典的例子. 实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓 ...
- JAVA多线程经典问题 -- 生产者 消费者
工作2年多来一直也没有计划写自己的技术博客,最近辞职在家翻看<thingking in JAVA>,偶尔看到了生产者与消费者的一个经典的多线程同步问题.本人在工作中很少使用到多线程以及高并 ...
- Java 管程解决生产者消费者问题
同样是实验存档.//.. 依然以生产者消费者问题作为背景. 管程(=“资源管理程序”)将资源和对资源的操作封装起来,资源使用者通过接口操作资源就 ok,不用去考虑进程同步的问题. 管程: packag ...
- java 多线程 22 :生产者/消费者模式 进阶 利用await()/signal()实现
java多线程15 :wait()和notify() 的生产者/消费者模式 在这一章已经实现了 wait/notify 生产消费模型 利用await()/signal()实现生产者和消费者模型 一样 ...
随机推荐
- 在block函数中规避错误信息 "capturing self strongly in this block is likely to lead to a retain cycle”
以形如 _fontValueChangedBlock = ^(){ [self.fontSmallButton addTarget:self action:@selector(btnFontSmall ...
- C#中几种数据库的大数据批量插入
C#语言中对SqlServer.Oracle.SQLite和MySql中的数据批量插入是支持的,不过Oracle需要使用Orace.DataAccess驱动. IProvider里有一个用于实现批量插 ...
- 滚动条加粗和panel,gridControl结合用
private void FrmLotterycs_Load(object sender, EventArgs e) { t = 0; UserJuanquanTB = O.get_UserJuanq ...
- 2016年7款最流行的Java框架
虽然Java一直被唱衰,但是直到现在Java也坚持霸主地位不动摇,毫无疑问,Java是目前最热门的编程语言之一,所以我们为大家搜集了一些目前比较受欢迎的Java框架的消息. 根据RebelLabs对在 ...
- VNC VIEWER的使用集锦
关于颜色深度的问题, 今天用VNC Viewser ,连上去之后,发现色彩可能只有8或者16位 然后修改了 sever的depth,也不好使, 于是,就修改了 client的 colourlevel ...
- Process 'command '/usr/lib/jvm/jdk1.8.0_25/bin/java'' finished with non-zero exit value 2
这个问题有两种可能,第一是jar包或者依赖冲突(版本冲突也算).第二是65535. 对于65535的问题,请看http://blog.csdn.net/t12x3456/article/details ...
- Entity Framework技巧系列之十三 - Tip 51 - 55
提示51. 怎样由任意形式的流中加载EF元数据 在提示45中我展示了怎样在运行时生成一个连接字符串,这相当漂亮. 其问题在于它依赖于元数据文件(.csdl .ssdl .msl)存在于本地磁盘上. 但 ...
- Android Studio的使用(十四)--如何查看资源或者函数在哪些类中被引用
1.我们都知道在Eclipse中可以通过快捷键Ctrl+Shift+G开快速搜索方法.类.资源都在那个类中被使用了. 2.在Android Studio中则使用快捷键Ctrl+G.
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;方法意思
这个方法是用来设置你的TableView中每一行显示的内容和格式的. indexPath 用来指示当前单元格,它的row方法可以获得这个单元格的行号,section方法可以获得这个单元格所处的区域号 ...
- php数据排序---array_multisort
PHP代码 <?php $ar1 = array(10, 100, 100, 0); $ar2 = array(1, 3, 2, 4); array_multisort($ar1, $ar2); ...