浅谈Java简单实现的生产者与消费者问题
一、面对生产者和消费者的问题,首先我们得明白几点:
生产者:生产数据;
消费者:消费数据。
消费者在没有数据可供消费的情况下,不能消费;
生产者在原数据没有被消费掉的情况下,不能生产新数据。
假设,数据空间只有一个。
实际上,如果实现了正确的生产和消费,则,两个线程应该是严格的交替执行。
synchronized关键字若用在代码中,形成一个同步块,且,必须要执行锁:
synchronized (锁对象) {
同步块
}
同步块使得锁对象称为thread monitor
二、代码实现:
1.首先我们建立一个生产者和消费者共同拥有的锁的类:
package com.mec.about_procuder_customer.core;
public class ProcuderCustomer {
//初始状态的数据为0个
protected static volatile int count = 0;
//执行锁
protected final static Object lock = new Object();
}
上述代码有一个关键字volatile,它是保证线程之间有序的一种方式,最重要也是最直接的是禁止寄存器优化。就是如果线程run方法中只是一个循环,并没有执行语句,那么,这个线程将不会执行。
2.我们再来建立一个生产者的类:
package com.mec.about_procuder_customer.core; //生产者
public class Procuder extends ProcuderCustomer implements Runnable { //存放数据的空间
private int[] dataSpace; public Procuder(int[] dataSpace, String threadName) {
this.dataSpace = dataSpace;
//启动线程
new Thread(this, threadName).start();
} @Override
public void run() {
int i = 0; while (true) {
synchronized (lock) {
//判断是否空间已满
if (count < dataSpace.length) {
//产生者放数据
dataSpace[count] = i++;
System.out.println("[" + Thread.currentThread().getName()
+ "]线程生产了一个数:" + dataSpace[count++]
+ " " + count);
try {
//只是为了看的清楚,沉睡2秒
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
//唤醒消费者
lock.notify();
} else {
try {
//使自己处于阻塞状态
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
3.建立消费者的类:
package com.mec.about_procuder_customer.core; //消费者
public class Customer extends ProcuderCustomer implements Runnable {
//存放数据的空间
private int[] dataSpace; public Customer(int[] dataSpace, String threadName) {
this.dataSpace = dataSpace;
//启动线程
new Thread(this, threadName).start();
} @Override
public void run() {
while (true) {
//加锁
synchronized (lock) {
//判断是否有数据
if (count > 0) {
System.out.println("[" + Thread.currentThread().getName()
+ "]线程消费了一个数:" + dataSpace[--count]);
//唤醒生产者
lock.notifyAll();
} else {
try {
//使自己处于阻塞状态
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
} }
4.测试类:
package com.mec.about_procuder_customer.test; import com.mec.about_procuder_customer.core.Customer;
import com.mec.about_procuder_customer.core.Procuder; public class Test { public static void main(String[] args) {
int[] data = new int[10];
new Procuder(data, "生产者1");
new Procuder(data, "生产者2");
new Customer(data, "消费者");
} }
运行结果:

浅谈Java简单实现的生产者与消费者问题的更多相关文章
- 浅谈Java的throw与throws
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
- 浅谈Java中的equals和==(转)
浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...
- 浅谈Java中的equals和==
浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: String str1 = new String("hello"); String str2 = ...
- 浅谈java性能分析
浅谈java性能分析,效能分析 在老师强烈的要求下做了效能分析,对上次写过的词频统计的程序进行分析以及改进. 对于效能分析:我个人很浅显的认为就是程序的运行效率,代码的执行效率等等. java做性能测 ...
- 浅谈Java中的深拷贝和浅拷贝(转载)
浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...
- !! 浅谈Java学习方法和后期面试技巧
浅谈Java学习方法和后期面试技巧 昨天查看3303回复33 部落用户大酋长 下面简单列举一下大家学习java的一个系统知识点的一些介绍 一.java基础部分:java基础的时候,有些知识点是非常重要 ...
- 浅谈Java中的深拷贝和浅拷贝
转载: 浅谈Java中的深拷贝和浅拷贝 假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(bool ...
- 【转】浅谈Java中的hashcode方法(这个demo可以多看看)
浅谈Java中的hashcode方法 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native i ...
- 浅谈java类集框架和数据结构(2)
继续上一篇浅谈java类集框架和数据结构(1)的内容 上一篇博文简介了java类集框架几大常见集合框架,这一篇博文主要分析一些接口特性以及性能优化. 一:List接口 List是最常见的数据结构了,主 ...
随机推荐
- DGUT_FLY退役贴 && FunCfans毕业总结-竞赛篇
严格来说我们飞跃队是去年ECFinal之后就退役的,只是这几个月有一堆事情在那,考研的考研,求职的求职,都把博客晾一边了.现在,总算能写点东西了. 我与ACM-ICPC的结缘,是从大一开学1个多月后开 ...
- 常用MarkDown标记
1:加粗 两个*号 加粗 2:代码段 三个` 代码段
- 运行android模拟器,emulator: ERROR: x86 emulation currently requires hardware acceleration!
运行android模拟器,emulator: ERROR: x86 emulation currently requires hardware acceleration! 问题: 运行android模 ...
- 病毒注册表常用目标Svchost和Explorer
Windows系统的Svchost.exe和Explorer.exe两种进程,作为Windows系统中两种重要的进程,下面我们就来看看他们的特点以及在各个操作系统中的应用. Explorer.exe ...
- 10: vue-router和单文件组件
1.1 vue-router路由基本使用 官网: https://router.vuejs.org/zh/api/#router-link 1.安装vue-router bower info vue- ...
- 基于QProbe创建基本Android图像处理框架
先来看一个GIF 这个GIF中有以下几个值得注意的地方 这个界面是基本的主要界面所应该在的地方.其右下角有一个“+”号,点击后,打开图像采集界面 在这个界面最上面的地方,显示的是当前图像处理的状态.( ...
- P3128 [USACO15DEC]最大流Max Flow
思路 这个题哪里有那么费脑筋 我们可以树链剖分嘛LCT昨天学的时候睡着了,不是太会 两遍dfs+一个5行的BIT 其实树链剖分学好了对倍增和LCT理解上都有好处 一条路径上的修改 由于一条剖出来的链是 ...
- CF 1087解题报告
cf解题报告 记录一下吧 做出:T1 rating :-97 想起几个月前做不出T1还是有点小搞笑呀2333 T1 双指针+特判 T2 发现k特别小,枚举剩余系 还要判断是否是能被n整除 移项发现可以 ...
- SpringBoot 使用validation数据校验
后端对数据进行验证 添加包 hibernate-validator <!-- https://mvnrepository.com/artifact/org.hibernate.validator ...
- IDEA查看一个类的所有继承关系
通常一个.java文件对应一个java类. 鼠标右击一个类: 即可查看.按住alt键可放大. 另一快捷键:光标在类名上,ctrl+H