用java编写生产者消费者程序
来源:互联网 发布:卡盟外包系统源码 编辑:程序博客网 时间:2024/06/11 13:33
花了点时间写了生产者消费者的小程序,凑和凑和.......
假设cd店中有固定的两种cd。编写一个线程类为cd店进货,一个线程类为会员买cd。
要求:
进货线程只有1个,固定的每1000ms启动一次,但是如果临时缺货则购买线程发送消息10ms后启动一次,每次为两种cd各购买10个。
销售线程可以有2个或2个以上,启动的时间为500ms以内的随机数。购买数量为5以内的随机数。如果cd数量不足则随机选择等候或放弃。
程序运行1分钟后停止,最后列出销售和购买记录。
import java.util.Random;
import java.util.concurrent.Semaphore;
class Producer implements Runnable{
private long nowstarttime;
private long laststarttime;
private static int wake_sleep_time = 10; //被唤醒时需睡眠一段时间
public Producer()
{
laststarttime = System.currentTimeMillis();
}
public void run() //进货线程
{
while(true)
{
try{
nowstarttime = System.currentTimeMillis();
if((nowstarttime-laststarttime) < main.wait_time) //被唤醒时进货前先睡眠一段时间
{
System.out.println("producer called up by customer");
Thread.sleep(wake_sleep_time); //进货前先休眠
}
main.produce(); //进货
laststarttime = nowstarttime; //记录上次运行时间
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class Customer extends Thread{ //销售线程
private static int id = 1;
private int customerid;
private static int time_start = 500; //购买线程启动时间最大值
public Customer()
{
customerid = id++;
this.setName("customer "+customerid); //消费者编号
}
public void run()
{
try {
while(true)
{
int sleep_time = main.randint(time_start); //随机睡眠时间
Thread.sleep(sleep_time);
boolean enough = main.buy(); //是否购买成功
if(!enough) //购买失败
{
if(sleep_time%2 == 0) //根据随机睡眠时间决定是否等待
{
System.out.println(Thread.currentThread().getName()+" give up"); //放弃
break;
}
else
{
System.out.println(Thread.currentThread().getName()+" wait"); //等待
}
}
else //购买成功
break;
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class main {
/**
* @param args
*/
private static int customer_thread_count = 500; //销售线程数量
private static int cd_want = 5; //每次购买数量最大值
public static int wait_time = 1000; //每隔固定时间启动进货线程
private static Object wake_sign = new Object(); //唤醒线程同步信号
private static int cd1_instore = 0; //当前库存的CD1数量
private static int cd2_instore = 0; //当前库存的CD1数量
private static Semaphore mutex = new Semaphore(1); //互斥信号量
public static int randint(int number) //产生number以内的随机数
{
Random rnd = new Random();
return rnd.nextInt(number);
}
public static void produce()
{
try
{
mutex.acquire(); //进入临界区
cd1_instore += 10; //增加库存
cd2_instore += 10;
System.out.println("produce success!");
mutex.release(); //离开临界区
synchronized(wake_sign)
{
wake_sign.wait(wait_time); //每隔一段时间进货或等待销售线程唤醒
}
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
public static boolean buy()
{
int cd1_want = randint(cd_want); //购买CD1数量
int cd2_want = randint(cd_want-cd1_want); //购买CD2数量
try
{
mutex.acquire(); //进入临界区
if((cd1_want <= cd1_instore) && (cd2_want <= cd2_instore)) //库存CD是否足够
{
cd1_instore -= cd1_want; //购买成功
cd2_instore -= cd2_want;
System.out.println(Thread.currentThread().getName()+
" get:"+" CD1 "+cd1_want+" CD2 "+cd2_want+" success");
mutex.release(); //离开临界区
return true;
}
else
{
System.out.println(Thread.currentThread().getName()+
" get:"+" CD1 "+cd1_want+" CD2 "+cd2_want+" fail");
mutex.release(); //离开临界区
synchronized(wake_sign)
{
wake_sign.notifyAll(); //唤醒进货线程
}
return false; //购买失败
}
} catch (InterruptedException e) {
e.printStackTrace();
return false;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("start process");
long runtime = 60000; //程序运行时间
long starttime = System.currentTimeMillis();
new Thread(new Producer()).start(); //启动进货线程
for(int i = 0; i < customer_thread_count; i++)
new Customer().start(); //销售线程
do
{
long endtime = System.currentTimeMillis();
if(endtime-starttime >= runtime) //运行1分钟停止
System.exit(0);
}while(true);
}
}
程序写下来,才发现线程等待和唤醒线程wait和notifyAll的调用对象是Object,而不是线程Thread,关系还是有点乱,学艺不精啊.......
- 用java编写生产者消费者程序
- Java生产者消费者程序模型
- 用Swift3.0和Java编写生产者消费者模式
- 生产者消费者代码编写
- 操作系统生产者与消费者程序(JAVA版)
- 多生产者和多消费者---Java程序
- Java多线程实现生产者消费者程序
- 生产者消费者程序的实现 Java
- 生产者消费者模拟程序
- 生产者消费者模拟程序
- 生产者消费者程序
- 生产者、消费者程序练手
- 编写一个生产者消费者模式的JAVA工程
- 用JAVA 实现“生产者-消费者”问题
- 用JAVA 实现“生产者-消费者”问题
- 用java实现生产者和消费者问题
- 用Java实现生产者消费者问题
- 用JAVA 实现“生产者-消费者”问题
- Freescale P4080 I2C 驱动分析
- JQuery知识
- 火狐插件 YSlow插件帮助测试网站的加载速度
- Maven pom文件常用配置小结
- 自己DIY脱机下载- 硬件篇
- 用java编写生产者消费者程序
- 4.1.3,int *p = NULL 和*p = NULL 有什么区别?
- WIN API-VFP取得任务栏的尺寸(宽度和高度)及位置
- Android 使用Matrix实例
- 谈谈C#中的修饰符
- 谷歌最新的天气报告:熊猫飑警告
- 成功安装MAC OS X 10.4.8
- 函数式编程扫盲篇
- ArcGIS API for Flex的Navigation slider的风格样式及定位