Java实现多线程生产者消费者模式的两种方法
生产者消费者模式:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据。生产者生产一个,消费者消费一个,不断循环。
第一种实现方法,用BlockingQueue阻塞队列来实现
LinkedBlockingQueue和ArrayBlockingQueue这两个类都实现了接口BlockingQueue,我们可以用这两个阻塞队列来处理多线程间的生产者消费者问题。
1.LinkedBlockingQueue:

主要方法:
- put(E e): 这个方法用于向BlockingQueue中插入元素,如果BlockingQueue没有空间,则调用此方法的线程被阻断直到BlockingQueue里有空间再继续。
- E take(): 这个方法用于取走BlockingQueue里面排在首位的对象,如果BlockingQueue为空,则调用线程被阻塞,进入等待状态,直到BlockingQueue有新的数据被加入。
实现生产者消费者问题
ConsumerQueue.java 消费者类
public class ConsumerQueue implements Runnable { private final BlockingQueue conQueue; public ConsumerQueue(BlockingQueue conQueue) {
this.conQueue = conQueue;
} @Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
System.out.println("消费者消费的商品编号为 :" + conQueue.take());
Thread.sleep(300); // 在这里sleep是为了看的更加清楚些 } catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
} }
}
}
ProducerQueue.java 生产者类
public class ProducerQueue implements Runnable { private final BlockingQueue proQueue; public ProducerQueue(BlockingQueue proQueue) {
this.proQueue = proQueue;
} int task = 1; @Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
proQueue.put(task);
System.out.println("生产者生产的商品编号为 : " + task);
task++;
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
}
SharedQueue.java 启动
public class SharedQueue {
public static void main(String[] args) {
/*
* 1.ArrayBlockingQueue必须指定队列大小,是有界的
* 2.LinkedBlockingQueue可以不指定队列大小,无界,默认大小为Integer
* .MAX_VALUE;也可以指定队列大小,变成有界的
*/
// BlockingQueue blockingQueue = new ArrayBlockingQueue(10);
BlockingQueue sharedQueue = new LinkedBlockingQueue(2); // 定义了一个大小为2的队列 Thread pro = new Thread(new ProducerQueue(sharedQueue));
Thread con = new Thread(new ConsumerQueue(sharedQueue)); pro.start();
con.start();
} }
第二种:通过java提供的等待唤醒机制来解决 多线程常用函数:
getThread.java 消费者类
public class getThread implements Runnable { private Student student; public getThread(Student student) {
this.student = student;
} @Override
public void run() {
// TODO Auto-generated method stub
while (true) {
synchronized (student) {
// 消费者没用数据就等待
while (!student.flag) {
try {
student.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(student.name + "------" + student.age);
// 消费完了就置为false没有
student.flag = false;
student.notify();
}
}
} }
setThread.java 生产类
public class setThread implements Runnable { private Student student;
private int x = 0; public setThread(Student student) {
this.student = student;
} @Override
public void run() {
// TODO Auto-generated method stub
while (true) {
synchronized (student) {
// 生产者有数据就等待,修改为while,保证每次wait()后再notify()时先再次判断标记。
while(student.flag){
try {
student.wait(); // 等待,会同时释放锁;将来醒过来的时候,就是在这里醒过来的。
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (x % 2 == 0) {
student.name = "AAA";
student.age = 22;
} else {
student.name = "BBB";
student.age = 24;
}
x++; //修改标记
student.flag = true;
student.notify();
}
}
} }
学生资源类
public class Student {
//同一个包下可以访问
String name;
int age;
boolean flag; // 默认情况是没有数据,如果有就是true
}
Main
public class StudentDemo {
public static void main(String[] args){
Student student = new Student();
setThread st = new setThread(student);
getThread gt = new getThread(student); Thread t1 = new Thread(st);
Thread t2 = new Thread(gt); t1.start();
t2.start();
} }
运行结果:

Java实现多线程生产者消费者模式的两种方法的更多相关文章
- java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-【费元星Q9715234】
java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-[费元星Q9715234] 说明如下,不懂的问题直接我[费元星Q9715234] 1.反射的意义在于不将xml tag ...
- java 多线程并发系列之 生产者消费者模式的两种实现
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据 ...
- java实现多线程生产者消费者模式
1.概念 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消 ...
- Java设计模式之生产者消费者模式
Java设计模式之生产者消费者模式 博客分类: 设计模式 设计模式Java多线程编程thread 转载 对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的.就像学习每一门编程语言一 ...
- Java构造和解析Json数据的两种方法详解二
在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面接着介绍用org.json构造和解析Jso ...
- Java构造和解析Json数据的两种方法详解二——org.json
转自:http://www.cnblogs.com/lanxuezaipiao/archive/2013/05/24/3096437.html 在www.json.org上公布了很多JAVA下的jso ...
- Java构造和解析Json数据的两种方法详解一——json-lib
转自:http://www.cnblogs.com/lanxuezaipiao/archive/2013/05/23/3096001.html 在www.json.org上公布了很多JAVA下的jso ...
- Java执行shell脚本并返回结果两种方法的完整代码
Java执行shell脚本并返回结果两种方法的完整代码 简单的是直接传入String字符串,这种不能执行echo 或者需要调用其他进程的命令(比如调用postfix发送邮件命令就不起作用) 执行复杂的 ...
- DES加密 java与.net可以相互加密解密两种方法
DES加密 java与.net可以相互加密解密两种方法 https://www.cnblogs.com/DrWang/archive/2011/03/30/2000124.html sun.misc. ...
随机推荐
- Asp.Net 加载不同项目程序集
我们做项目时有时候不想添加别的项目的引用,但是那个项目又必须在 Global 中进行注册 最常见的就是插件机制,参考: https://shazwazza.com/post/Developing-a- ...
- input 被checked时和label配合的妙用
input 和label配合的妙用 1:作为文字隐藏与否的开关: 如下代码:对div里面所包含的文字较多,一开始只展示小部分,当用户点击按钮时,进行全部内容的展示(按钮是以向下隐藏箭头的图片) htm ...
- EntityFramework进阶(一)- DbContext与ObjectContext互转
本系列原创博客代码已在EntityFramework6.0.0测试通过,转载请标明出处 EF中我们常用的是DbContext作为上下文,如果要想获取元数据等信息还是要用到ObjectContext这个 ...
- 为满足中国税改,SAP该如何打SPS
*****一定要先阅读这个note***** ***** 2736625 - [ZH] 应对2019中国个税改革,SAP系统升级常见问题汇总 **** 1784328 - How to check C ...
- Eclipse 交叉编译环境
创建空工程 添加交叉编译环境 添加工程文件 如需修改交叉编译环境 Cross GCC:使用交叉编译命令编译,需要自己指定 MinGW GCC:使用make命令编译,需要有Makefile Make T ...
- S3C2440 块设备(待续)
1.块设备只能以块为单位接受输入和返回输出,而字符设备则以字节为单位 2.块设备对于I/O请求有对应的缓冲区,因此他们可以选择以什么顺序进行响应,字符设备无须缓冲且被直接读写.对于存储设备而言调整读写 ...
- 类中变量私有化和调用:__x和getx/setx或者property
__xx:双前置下划线,子类不可继承属性.方法,父类私有. 详见:https://www.cnblogs.com/andy9468/p/8299448.html 例子1:隐藏数据:私有化后,用get和 ...
- 解决Apache启动错误:httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
启动apache遇到提示: [root@bqh-119 conf]# ../bin/apachectl -thttpd: apr_sockaddr_info_get() failed for bqh- ...
- 国内首本免费深度学习书籍!还有人没Get么?
这本书的作者很有趣鸭. 一开篇别的不说,先跟大家讲哲学,讨论人工智能实现的可能性.摘录一些他的结论: 人工智能可以实现 自由意志并不存在 量子力学并不能证明自由意志的存在 幸福感和物质水平提高并没有绝 ...
- 助教培训第四次作业——熟练掌握GitHub及Git的使用方法
助教培训第四次作业——熟练掌握GitHub及Git的使用方法 1.Git 命令的理解和使用 常用的Git命令可以查看官方文档,官方文档的网址:https://git-scm.com/docs .虽然是 ...