前言
利用线程同步和线程通信实现这样一个过程:有一个煎饼摊,规定每天只做10个煎饼,卖完才能收摊,并且要保证任意时刻煎饼摊的煎饼数不能超过3个,如果顾客来的时候煎饼数为0,那么该顾客就要等待煎饼做好才能购买。利用线程来模拟这样一个过程,要求:打印出从开始制作煎饼到10个煎饼全部卖完的整个过程。
输出样例:
一、关键技术
线程同步,线程通信,生产者-消费者模型,共享数据类,共享数据控制类
二、步骤
1.创建共享数据类
设置一个共享数据类(有点像是利用全局变量来计数,只不过将变量封装在类中)
代码如下(示例):
//共享数据类,其中的数据都是作为共享数据,方便共享数据控制类的访问
public class Mycake {
public int count = 0; //记录当天做的煎饼数
public int sell = 0; //记录当天卖出的煎饼数
public Mycake() {
}
}
2.创建一个共享数据控制类
共享数据控制类,对共享数据类中的变量值进行修改
代码如下(示例):
//共享数据控制类,对做煎饼和卖煎饼过程的控制
class Sharecake { //控制煎饼的制作和出售
public Mycake mycake;
public int flag = 0; //标志,记录当前还有几个煎饼
Sharecake() {
}
public synchronized void setSharecake(Mycake mycake) { //该方法控制煎饼的制作
//定义为同步方法,保证在同一个时刻只能有一个线程访问该方法
if (this.flag == 3) {
try {
System.out.println("还有三个煎饼未出售,请卖出后再制作");
this.wait(); //让生产者线程休眠,等待唤醒
} catch (InterruptedException var3) {
}
}
//当剩余的煎饼少于三个时,正常制作煎饼
this.mycake = mycake;
++this.flag;
++mycake.count;
this.notify(); //制作完成,唤醒消费者线程
}
public synchronized Mycake getSharecake() { //该方法控制煎饼的出售
if (this.flag == 0) {
try {
System.out.println("抱歉,没有做好的煎饼,顾客需要等待");
this.wait(); //让消费者线程等待
} catch (InterruptedException var2) {
}
}
//正常售出煎饼
--this.flag;
++this.mycake.sell;
this.notify(); //卖出煎饼,唤醒生产者线程
return this.mycake;
}
}
3.定义一个生产者类
生产者线程,判断该不该生产
代码如下(示例):
class Producer implements Runnable { //商家完成做煎饼的动作,所以使用控制类中的做煎饼的动作(方法)
private static final int MAKE = 1000; //自定义的休眠时间
private Sharecake s;
Producer(Sharecake s) {
this.s = s;
}
public void run() {
Mycake mycake = new Mycake();
do {
try {
Thread.sleep(MAKE);
} catch (InterruptedException var3) {
}
this.s.setSharecake(mycake);
System.out.println("做好了一个煎饼,这是今天做的第" + mycake.count + "个煎饼");
} while(mycake.count < 10);
System.out.println("今天的10个煎饼已经制作完成!");
}
}
4.定义一个消费者类
消费者线程,判断顾客是否需要等待,还是可以直接购买
代码如下(示例):
class Consumer implements Runnable { //顾客消费,使用控制类中的出售动作(方法)
Sharecake s;
Consumer(Sharecake s) {
this.s = s;
}
public void run() {
Mycake mycake;
do {
try {
Thread.sleep((long)((int)(Math.random() * 10000)));
//利用随机函数来产生休眠时间来模拟顾客的不确定性
} catch (InterruptedException var3) {
}
mycake = this.s.getSharecake();
System.out.println("卖出一个煎饼,还剩" + this.s.flag + "个煎饼,这是今天卖出的第" + mycake.sell + "个煎饼");
} while(mycake.sell >= 0 && mycake.sell < 10);
System.out.println("今天的10个煎饼已经制作完成,可以收摊了!");
}
}
5.主函数
逻辑控制
package com.company;
public class Main {
public static void main(String[] args) {
Sharecake s=new Sharecake(); //控制对象
Producer p=new Producer(s);
Consumer c=new Consumer(s);
Thread thread1=new Thread(p); //创建一个生产者线程
Thread thread2=new Thread(c);
thread1.start();
thread2.start();
}
}