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. ...
随机推荐
- 使用async和await的异步编程
异步编程模型(TAP)提供了抽象的异步代码.异步代码看起来和同步代码没什么大的区别,无非多个了两个关键字(async和await).但是代码的执行顺序并没看起来那么简单,代码的执行顺序根据cpu资源的 ...
- 【转载】C#中PadLeft函数按特定字符补足字符串长度
在C#开发过程中字符串String类处理过程中,有时字符串长度不够时,需要在左侧指定特定的字符来补足字符串长度,此时可以使用String类下的PadLeft方法对字符串的左边进行按特定的字符和特定的长 ...
- OpenStack kilo版(2) keystone部署
部署在controller节点 配置数据库 MariaDB [(none)]> CREATE DATABASE keystone; Query OK, 1 row affected (0.00 ...
- Dockerfile的编写(主观汇聚篇)
目录 一.什么是dockerfile 二.Dockerfile的基本结构 Dockerfile文件说明 三.总结 一.什么是dockerfile dockerfile是使用者用来自定义构建一个dock ...
- Mysql 中的SSL 连接
Mysql 中的SSL 连接 以下来自网络参考和自己测试整理,没有查找相关资料.若有错误之处,欢迎指正. 当前的Mysql 客户端版本基本都不太能支持 caching_sha2_password 认证 ...
- Android笔记(十五) Android中的基本组件——单选框和复选框
单选框和多选框通常用来在设置用户个人资料时候,选择性别.爱好等,不需要用户直接输入,直接在备选选项中选择,简单方便. 直接看代码: <?xml version="1.0" e ...
- [leetcode]存在重复
题目描述: 给定一个整数数组,判断是否存在重复元素. 如果任何值在数组中出现至少两次,函数返回 true.如果数组中每个元素都不相同,则返回 false. 示例 1: 输入: [1,2,3,1] 输出 ...
- 2.Git 结构
1.Git 结构: 使用git add命令将写的代码暂存到暂存区:使用git commit命令将暂存区的代码提交到本地库: 2. Git 结构及其代码托管中心: workSpace:工作区(写代码). ...
- Tensorflow&CNN:裂纹分类
版权声明:本文为博主原创文章,转载 请注明出处:https://blog.csdn.net/sc2079/article/details/90478551 - 写在前面 本科毕业设计终于告一段落了.特 ...
- Win8.1 Anaconda下安装第三方库,以jieba wordcloud为例
最近在看情感分析的东西,于是在spyder里import jieba,and then就报错了. 百度之后,发现jieba是一个第三方库,它并不存在于anaconda内置的packages中.所以在用 ...