实例题目:
1.在一个KFC内,服务员负责生产食物,消费者负责消费食物;
2.当生产到一定数量可以休息一下,直到消费完食物,再马上生产,一直循环
程序涉及到的内容:
1.这设计到java模式思想:生产者消费者模式
2.要保证操作对象的统一性,即消费者和服务者都是跟同一个KFC发生关系的,KFC只能new一次
3.this.notifyAll();和 this.wait();一个是所有唤醒的意思,一个是让自己等待的意思;
比如本题中,生产者生产完毕后,先所有唤醒(包括消费者和生产者),再让所有自己(生产者)等待
这时,消费者开始消费,直到食材不够,先所有唤醒(包括消费者和生产者),再让所有自己(消费者)等待
一直执行上面的操作的循环
4.生产者和消费者都要继承Thread,才能实现多线程的启动
程序设计的步骤思路:
1.创建一个食物类Food,有存放/获取食物的名称的数量
2.创建一个KFC类,有生产食物和消费食物的方法
3.创建一个客户类Customer,继承Thread,重写run方法,在run方法里面进行消费食物操作
4.创建一个服务员类Produce,继承Thread,重写run方法,在run方法里面进行生产食物的操作
5.创建主方法的调用类
Food类
public class Food {
public final static int max = 20;//大于最大食材数,生产者释放锁,处于等待状态
public final static int min = 5;//小于最小食材数,消费者释放锁,处于等待状态
public static int hamburger = 20;//初始食材数
}
KFC类
public class KFC {
public void produce(int index, String name) {
try {
synchronized (this) {
//notifyAll和wait需要在锁内,否则调用方法时会报获取对象异常
this.notifyAll();
Food.hamburger = Food.hamburger + index;
System.out.println("食材补充了" + index + ",生产者为" + name+ ",剩余总量为" + Food.hamburger);
if (Food.hamburger >= Food.max) {
System.out.println("食材剩余总量充足,暂停生产");
// 使用wait时,需要保证此线程正在使用
this.wait(100);
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void custom(int index, String name) {
try {
synchronized (this) {
//唤醒所有线程,允许获取锁
this.notifyAll();
Food.hamburger = Food.hamburger - index;
System.out.println("食材消耗了" + index + ",消费者为" + name+ ",剩余总量为" + Food.hamburger);
if (Food.hamburger <= Food.min) {
System.out.println("食材剩余不足,请及时生产生产");
//释放当前线程锁,并休眠
this.wait(100);
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Customer类
public class Customer extends Thread {
public KFC kfc;
public String name;
public Customer(KFC kfc,String name){
this.kfc=kfc;
this.name=name;
}
public void run(){
//食材数大于最小食材数时可以进行消费
while (Food.hamburger > Food.min) {
kfc.custom(3, name);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Produce类
public class Produce extends Thread {
public KFC kfc;
public String name;
public Produce(KFC kfc,String name){
this.kfc=kfc;
this.name=name;
}
public void run(){
//当食材数小于最大食材数时,就可以进行生产
while (Food.hamburger < Food.max) {
kfc.produce(5, name);
try {
//此线程休眠1秒,否则会造成都是同一个人生产的结果
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
主函数调用类
public class Main {
//生产者消费者例子
public static void main(String[] arg0){
// 只实例化一个KFC对象,保证每一个服务员和用户在同一个KFC对象内
KFC kfc = new KFC();
//实例化2个客户对象
Customer c1 = new Customer(kfc,"客户A");
Customer c2 = new Customer(kfc,"客户B");
//实例化2个服务员对象
Produce waiter1 = new Produce(kfc,"生产者A");
Produce waiter2 = new Produce(kfc,"生产者B");
//让所有的对象的线程都开始工作
waiter1.start();
waiter2.start();
c1.start();
c2.start();
}
}
最终效果