在操作系统中有一类问题被称为生产者消费者问题:意为,有数个生产者生产产品,有数个消费者消费产品,他们共享一定数量的缓存。

这里用java多线程编程,实现生产者消费者问题的一种延伸,橘子苹果问题。

题目如下:

有苹果橘子生产者各20个,有苹果橘子消费者各20个,他们公用20个缓存区。要求能随时查看缓存区内容,随时查看生产消费内容情况,随时暂停生产开始生产。

我们的实现思路:

1.首先创建一个缓存区类,其中包含静态的,长度大小为20的数组,用来存放和取出生产的产品;一个静态的日志变量List,用来记录对缓存区的操作;

以及对缓存区的操作方法和对日志变量的操作方法。

2.创建苹果生产者类和橘子生产者类,他们继承Thread类,其中包含四个变量:缓存类的实例对象,生产者自己的id,运行周期,暂停信号量;以及对run方法的重写。

3.创建苹果消费者类和橘子消费者类,他们继承Thread类,其中包含四个变量:缓存类的实例对象,生产者自己的id,运行周期,暂停信号量;以及对run方法的重写。

4.在程序中添加静态代码块,初始时创建20个橘子生产者20个苹果生产者,20个橘子消费者,20个苹果消费者。

5.在程序开始时开启线程。

6.表现层我们可以利用jsp来实现,用ajax做刷新模仿实时更新(这里用jsp实现并不是最好的选择)

一下贴出实现代码:

缓存类

public class BufferCase {
private static List<String> buffer = new ArrayList<String>();
private static List<String> log = new ArrayList<String>();
//制造缓存内容
public synchronized boolean inBuffer(String goods){
if(buffer.size()==20)
return false;
else if(buffer.add(goods))
return true;
else
return false;
}
//消费缓存内容
public synchronized String outBuffer(int type){
for(int i=0;i<buffer.size();i++){
if(type==1){
if(buffer.get(i).equals("apple")){
buffer.remove(i);
return new String("apple");
}
}
if(type==2){
if(buffer.get(i).equals("orange")){
buffer.remove(i);
return new String("orange");
}
}
}
return null;
}
//写入日志内容
public synchronized void inLog(String log){
this.log.add(log);
}
//清除日志内容
public static synchronized void clearLog(){
log.clear();
}
//输出日志内容
public static List<String> outLog(){
return log;
}
//输出缓存内容
public static List<String> outBuffer(){
return buffer;
}
}

消费者类

public class OrangeConsumer extends Thread {
BufferCase buffer = null;
int time= 2000 ;//运行周期
boolean flag=true;//是否暂停
int id;//消费者id
public void setFlag(boolean flag){
this.flag = flag;
}
public void setTime(int time) {
this.time = time;
}
public OrangeConsumer(BufferCase bf,int id){
buffer = bf;
this.id = id;
} @Override
public void run() {
while(true){
// 设定运行周期
try {
sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
//消费橘子
synchronized(buffer){
if(flag==false)
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String goods = null;
goods = buffer.outBuffer(2);
if(goods==null)
buffer.inLog("橘子消费者"+id+"消费橘子失败");
else
buffer.inLog("橘子消费者"+id+"消费橘子成功");
}
super.run();
}
} }
public class AppleConsumer extends Thread{
public BufferCase buffer = null;
int time = 2000;//运行周期
boolean flag=true;//是否暂停
int id;//消费者id
public void setFlag(boolean flag){
this.flag = flag;
}
public void setTime(int time) {
this.time = time;
}
public int getTime(){
return this.time;
}
public AppleConsumer(BufferCase bf,int id){
buffer = bf;
this.id = id;
} @Override
public void run() {
while(true){
// 设定运行周期
try {
sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
//消费苹果 synchronized(buffer){
if(flag==false)
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String goods = null;
goods = buffer.outBuffer(1);
if(goods==null)
buffer.inLog("苹果消费者"+id+"消费苹果失败");
else
buffer.inLog("苹果消费者"+id+"消费苹果成功");
}
super.run();
}
}
}

生产者类

public class AppleProducer extends Thread {
BufferCase buffer = null;
int time= 2000 ;//运行周期
boolean flag=true;//是否暂停
int id;//消费者id
public void setFlag(boolean flag){
this.flag = flag;
}
public void setTime(int time) {
this.time = time;
}
public AppleProducer(BufferCase bf,int id){
buffer = bf;
this.id = id;
} @Override
public void run() {
while(true){
// 设定运行周期
try {
sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
//生产苹果
if(flag==true)
synchronized(buffer){
String goods = new String("apple");
if(buffer.inBuffer(goods))
buffer.inLog("苹果生产者"+id+"放入苹果成功");
else
buffer.inLog("苹果生产者"+id+"放入苹果失败");
}
super.run();
}
}
}
public class OrangeProducer extends Thread{
BufferCase buffer = null;
int time= 2000 ;//运行周期
boolean flag=true;//是否暂停
int id;//消费者id
public void setFlag(boolean flag){
this.flag = flag;
}
public void setTime(int time) {
this.time = time;
}
public OrangeProducer(BufferCase bf,int id){
buffer = bf;
this.id = id;
} @Override
public void run() {
while(true){
// 设定运行周期
try {
sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
//生产橘子
if(flag==true)
synchronized(buffer){
String goods = new String("orange");
if(buffer.inBuffer(goods))
buffer.inLog("橘子生产者"+id+"放入橘子成功");
else
buffer.inLog("橘子生产者"+id+"放入橘子失败");
}
super.run();
}
}
}

初始化角色类:

public class AllRoles {
public static AppleConsumer[] ac = new AppleConsumer[20];
public static OrangeConsumer[] oc = new OrangeConsumer[20]; public static AppleProducer[] ap = new AppleProducer[20];
public static OrangeProducer[] op = new OrangeProducer[20]; static{
BufferCase bf = new BufferCase();
for(int i=0;i<20;i++){//初始化生产者消费者线程
ap[i] = new AppleProducer(bf,i);
op[i] = new OrangeProducer(bf,i); ac[i] = new AppleConsumer(bf,i);
oc[i] = new OrangeConsumer(bf,i);
}
}
}

各种业务逻辑

//开启线程
for(int i=0;i<20;i++){
AllRoles.ac[i].start();
AllRoles.ap[i].start();
AllRoles.oc[i].start();
AllRoles.op[i].start();
}
//暂停线程
for(int i=0;i<20;i++){
AllRoles.ac[i].setFlag(false);
AllRoles.ap[i].setFlag(false);
AllRoles.oc[i].setFlag(false);
AllRoles.op[i].setFlag(false);
}
//重启线程
for(int i=0;i<20;i++){
AllRoles.ac[i].setFlag(true);
AllRoles.ap[i].setFlag(true);
AllRoles.oc[i].setFlag(true);
AllRoles.op[i].setFlag(true);
}

运行结果图:

Java多线程实现生产者消费者延伸问题的更多相关文章

  1. java多线程解决生产者消费者问题

    import java.util.ArrayList; import java.util.List; /** * Created by ccc on 16-4-27. */ public class ...

  2. java多线程模拟生产者消费者问题,公司面试常常问的题。。。

    package com.cn.test3; //java多线程模拟生产者消费者问题 //ProducerConsumer是主类,Producer生产者,Consumer消费者,Product产品 // ...

  3. JAVA多线程之生产者 消费者模式 妈妈做面包案例

    创建四个类 1.面包类 锅里只可以放10个面包 ---装面包的容器2.厨房 kitchen 生产面包 和消费面包  最多生产100个面包3.生产者4消费者5.测试类 多线程经典案例 import ja ...

  4. Java多线程_生产者消费者模式2

    在我的上一条博客中,已经介绍到了多线程的经典案列——生产者消费者模式,但是在上篇中用的是传统的麻烦的非阻塞队列实现的.在这篇博客中我将介绍另一种方式就是:用阻塞队列完成生产者消费者模式,可以使用多种阻 ...

  5. Java多线程-----实现生产者消费者模式的几种方式

       1 生产者消费者模式概述 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理 ...

  6. 【多线程】java多线程实现生产者消费者模式

    思考问题: 1.为什么用wait()+notify()实现生产者消费者模式? wait()方法可以暂停线程,并释放对象锁 notify()方法可以唤醒需要该对象锁的其他线程,并在执行完后续步骤,到了s ...

  7. Java多线程之生产者消费者问题&lt;一&gt;:使用synchronized keyword解决生产者消费者问题

    今天看了一片博文,讲Java多线程之线程的协作,当中作者用程序实例说明了生产者和消费者问题,但我及其它读者发现程序多跑几次还是会出现死锁,百度搜了下大都数的样例也都存在bug,经过细致研究发现当中的问 ...

  8. Java多线程_生产者消费者模式1

    生产者消费者模型       具体来讲,就是在一个系统中,存在生产者和消费者两种角色,他们通过内存缓冲区进行通信,生产者生产消费者需要的资料,消费者把资料做成产品.生产消费者模式如下图.(图片来自网络 ...

  9. Java多线程同步——生产者消费者问题

    这是马士兵老师的Java视频教程里的一个生产者消费者问题的模型 public class ProduceConsumer{ public static void main(String[] args) ...

随机推荐

  1. VS2010/MFC对话框三:创建对话框类和添加控件变量

    创建对话框类和添加控件变量 前两讲中讲解了如何创建对话框资源.创建好对话框资源后要做的就是生成对话框类了.生成对话框类主要包括新建对话框类.添加控件变量和控件的消息处理函数等. 例程Addition是 ...

  2. cocos2d-x的A*寻路

    如果你还不熟悉A*寻路,请先看下这篇文章http://blog.csdn.net/dssdss123/article/details/11494065 一.先介绍几个函数和结构: 1.virtual ...

  3. 常用的shell命令整理

    工作快一年了,shell命令也玩了一年了.还是有点积累的,下面是本人常用的. 1.pwd | xargs -i basename {}   获取当前所在目录的名称 2.ps -ef|grep -w   ...

  4. MVC自定义AuthorizeAttribute实现权限管理

    [转]MVC自定义AuthorizeAttribute实现权限管理 原文载自:小飞的DD http://www.cnblogs.com/feiDD/articles/2844447.html 网站的权 ...

  5. Xcode6中怎么添加空工程模板

    亲们!是不是还在为Xcode中不能创建空工程模板苦恼,轩哥为大家准备了一个脚本,可以在Xcode6中直接创建空工程,跟以前一样一样的! 按照以下要求就可以了!下载地址:里面有一个文档有详细的步骤htt ...

  6. Android 中 GridView 常用属性合集

    GridView的一些常用属性: android:numColumns=”auto_fit” //GridView的列数设置为自动 android:columnWidth=”90dp " / ...

  7. 2014 HDU多校弟五场J题 【矩阵乘积】

    题意很简单,就是两个大矩阵相乘,然后求乘积. 用 Strassen算法 的话,当N的规模达到100左右就会StackOverFlow了 况且输入的数据范围可达到800,如果变量还不用全局变量的话连内存 ...

  8. Socket编程模式

    Socket编程模式 本文主要分析了几种Socket编程的模式.主要包括基本的阻塞Socket.非阻塞Socket.I/O多路复用.其中,阻塞和非阻塞是相对于套接字来说的,而其他的模式本质上来说是基于 ...

  9. android如何添加桌面图标和卸载程序后自动删除图标

    android如何添加桌面图标和卸载程序后自动删除桌面图标,这是一个应用的安装与卸载过程对桌面图标的操作,下面与大家分享下具体是如何实现的,感兴趣的朋友可以参考下哈 1:创建图标如下 Intent i ...

  10. CMake初步(2)

    转自:<你所不知的OSG>第一章:CMake初步(2) http://bbs.osgchina.org/forum.php?mod=viewthread&tid=1229& ...