在看代码之前,笔者先说几句题外话,生产者-消费者模式,一直是多线程编程中的经典设计模式,不仅仅提现在Java中,各个类C语言,以及其他的一些高级语言中都有实现,在Java 5之前,还没有出现阻塞队列的容器时,实现一个生产者消费者模式,相对来说比较复杂,代码量也比较大,最重要的是设计同步存取时更需要小心谨慎,一不小心就会带来莫名其妙的问题。

Java 5之前实现同步存取时,可以使用普通的一个集合,然后在使用线程的协作和线程同步可以实现生产者,消费者模式,主要的技术就是用好,wait ,notify,notifyAll,sychronized这些关键字。而在java 5之后,可以使用组阻塞队列来实现,此方式大大简少了代码量,使得多线程编程更加容易,安全方面也有保障。

BlockingQueue接口是Queue的子接口,它的主要用途并不是作为容器,而是作为线程同步的的工具,因此他具有一个很明显的特性,当生产者线程试图向BlockingQueue放入元素时,如果队列已满,则线程被阻塞,当消费者线程试图从中取出一个元素时,如果队列为空,则该线程会被阻塞,正是因为它所具有这个特性,所以在程序中多个线程交替向BlockingQueue中放入元素,取出元素,它可以很好的控制线程之间的通信。

下面给出代码实现

package com.queue;

import java.util.concurrent.BlockingQueue;

/***

* 消费者

* **/

public class Consumer extends Thread {

/***

* 利用队列存储样品

* */

private BlockingQueue bq;

public Consumer() {

// TODO Auto-generated constructor stub

}

public Consumer(BlockingQueue bq) {

super();

this.bq = bq;

}

@Override

public void run() {

while(true){

System.out.println(getName()+"消费者准备消费集合元素");

try{

Thread.sleep(2000);

//尝试取出元素,如果队列为空,则被线程阻塞

bq.take();

}catch(Exception e){

e.printStackTrace();

}

System.out.println(getName()+"消费完成"+bq);

}

}

}

package com.queue;

import java.util.concurrent.BlockingQueue;

/**

* 生产者

* **/

public class Producer extends Thread{

/***

* 利用队列存储样品

* */

private BlockingQueue bq;

public Producer() {

// TODO Auto-generated constructor stub

}

public Producer(BlockingQueue bq) {

this.bq = bq;

}

@Override

public void run() {

String []str=new String[]{"solr","lucene","nutch"};

for(int i=0;i<99999999;i++){

System.out.println(getName()+"生产者准备生产集合元素了!");

try{

Thread.sleep(2000);

//尝试放入元素,如果对列已满,则线程被阻塞

bq.put(str[i%3]);

}catch(Exception e){

e.printStackTrace();

}

System.out.println(getName()+"生产完成:"+bq);

}

}

}

package com.queue;

import java.util.concurrent.ArrayBlockingQueue;

import java.util.concurrent.BlockingQueue;

/**

* 生产者,消费者测试

*

* **/

public class BlockingQueueTest {

public static void main(String[] args) {

//创建一个容量为1的队列

BlockingQueue bq=new ArrayBlockingQueue<>(1);

//启动三个生产者线程

new Producer(bq).start();

new Producer(bq).start();

new Producer(bq).start();

//启动一个消费者线程

new Consumer(bq).start();

}

}

Thread-0生产者准备生产集合元素了!

Thread-1生产者准备生产集合元素了!

Thread-2生产者准备生产集合元素了!

Thread-3消费者准备消费集合元素

Thread-0生产完成:[solr]

Thread-0生产者准备生产集合元素了!

Thread-3消费完成[]

Thread-3消费者准备消费集合元素

Thread-1生产完成:[solr]

Thread-1生产者准备生产集合元素了!

Thread-3消费完成[solr]

Thread-2生产完成:[solr]

Thread-2生产者准备生产集合元素了!

Thread-3消费者准备消费集合元素

Thread-3消费完成[lucene]

Thread-3消费者准备消费集合元素

Thread-0生产完成:[lucene]

Thread-0生产者准备生产集合元素了!

总之,利用好队列就可以用很少的代码量实现一个稳定,高效生产者,消费者模式,

分享到:

2013-07-22 12:14

浏览 5956

评论

1 楼

taoshi

2014-11-25

谢谢您分享.

java生产者消费者 阻塞_java之使用阻塞队列实现生产者,消费者模式相关推荐

  1. java socket readline 阻塞_java Socket readLine() 阻塞

    1,当使用调用 在服务器端调用readLine()的时候,客户端就如果调用的是print()方法就会卡住,而且不会报错,改成println() 就会畅通! 2,如果 socket端 while()循环 ...

  2. java循环的概念_Java数据结构之循环队列简单定义与用法示例

    本文实例讲述了Java数据结构之循环队列简单定义与用法.分享给大家供大家参考,具体如下: 一.概述: 1.原理: 与普通队列的区别在于循环队列添加数据时,如果其有效数据end == maxSize - ...

  3. java栈编程题_Java实现栈和队列面试题

    面试的时候,栈和队列经常会成对出现来考察.本文包含栈和队列的如下考试内容: (1)栈的创建 (2)队列的创建 (3)两个栈实现一个队列 (4)两个队列实现一个栈 (5)设计含最小函数min()的栈,要 ...

  4. java实现fifo算法_java算法:FIFO队列

    java算法:FIFO队列 FIFO队列是一个ADT,由两个基本操作构成:插入(放入)一个新项,删除(得到)最早插入的项. 例1:FIFO队列ADT接口 Java代码 interfaceintQueu ...

  5. 面试官系统精讲Java源码及大厂真题 - 23 队列在源码方面的面试题

    23 队列在源码方面的面试题 人要有毅力,否则将一事无成. 引导语 队列在源码方面的面试题,一般面试官会从锁,线程池等知识点作为问题入口,慢慢的问到队列,由于锁.线程池咱们还没有学习到,所以本章就直奔 ...

  6. java 生产者消费者_Java多线程:线程间通信—生产者消费者模型

    一.背景 && 定义 多线程环境下,只要有并发问题,就要保证数据的安全性,一般指的是通过 synchronized 来进行同步. 另一个问题是, 多个线程之间如何协作呢 ? 我们看一个 ...

  7. java多线程生产者与消费者问题_Java多线程详解之四:生产者消费者问题

    一.问题描述 生产者消费者问题(Producer-Consumer problem),也称有限缓冲区问题(Bounded-buffer promblem),是一个多线程同步问题的经典案例.对于一个固定 ...

  8. java让线程空转_Java锁:悲观/乐观/阻塞/自旋/公平锁/闭锁,锁消除CAS及synchronized的三种锁级别...

    JAVA LOCK 大全 [TOC] 一.广义分类:乐观锁/悲观锁 1.1 乐观锁的实现CAS (Compare and Swap) 乐观锁适合低并发的情况,在高并发的情况下由于自旋,性能甚至可能悲观 ...

  9. java生产者与消费者问题_java生产者与消费者问题

    为了回忆一下J2SE中的线程互斥与同步问题,所以今天就写个生产者与消费者问题.这个程序大部分时间的结果都基本正确,但某些时候会造成死锁.百思不得其解,将代码贴上,方便以后有更深的体会时再进行修改.也方 ...

  10. java 生产者消费者代码_Java生产者和消费者代码

    java 生产者消费者代码 This also helps us to understand the concept of synchronised multi-threading in java, ...

最新文章

  1. OSError: libcudart.so.8.0: cannot open shared object file: No such file or directory 解决方法
  2. 修改单个viewcontroller的状态栏字体颜色
  3. JVM参数设置、分析(转)
  4. python keras_深度学习:基于Keras的Python实践
  5. nginx轻松搭建自己的flv流媒体服务器
  6. boost 获取时间
  7. 驱动级的自动按键_太牛了!业余单片机爱好者用DS3231制作自动亮度的4位数码管时钟...
  8. AAAI'22 | 基于情感分析的开放域对话系统
  9. SameSite Cookie支持的浏览器版本
  10. 国家网信办《网络数据安全管理条例(征求意见稿)》为企业带来哪些新思考?
  11. 机械祭天法力无边:C++primer之书店程序包含Sales_item.h源码
  12. 轨迹(形状)相似性判断与度量方法
  13. 房间类游戏后台框架(一)—介绍
  14. DDOS防护如何建设?
  15. 奇虎360scribe日志采集系统
  16. Android Hybrid开发实战之图片的交互
  17. 可替换STM23G031的32位单片机
  18. Blazor开发WEB程序
  19. 矩阵合同与相似,为什么只有当C为正交阵时才能使既相似又合同?
  20. Linux基础入门教程

热门文章

  1. win7中inter信息服务器,Win7系统Internet选项在哪里?
  2. LeetCode 934.最短的桥
  3. 蓝牙模块定位_详解蓝牙4.0BLEbeacon室内定位原理
  4. html网页表格相同行自动合并,jQuery实现HTML表格单元格的合并功能
  5. hdu-4565(矩阵快速幂+推导)
  6. cesium之三维漫游飞行效果实现篇(转)
  7. 通过自定义注解+反射的形式,使用POI实现excel的导入导出
  8. 安装office 错误代码:30068-39
  9. python编程猜拳游戏_python代码实现猜拳小游戏
  10. LeetCode476