解决多消费者生产者的问题(两个方法)

多消费者生成者问题

利用同步代码块修饰

public class Desk {
private Integer count = 0;  //定义线程是第几次运行
private Boolean flag = false;//设置线程的一个状态 用来判断该调用哪个线程了
//因为该方法用了synchronized修饰 所以不会出现线程安全问题 又叫同步方法
public synchronized void makeFood() {
    // wait notifyAll 必须在同步代码块中synchronized
    try {
        while (flag) { //如果状态为ture 说明现在有餐桌上面有东西 厨子这个线程应该去等待
            this.wait();
        }
        //如果flag为false 说明现在餐桌上没食物  厨子该去做食物
        count++;
        System.out.println(Thread.currentThread().getName() + "做了第" + count + "个包子");
        //厨子做好了 用一个状态标记下已经做好了 方面吃货能做出判断 知道东西做好了 可以吃了
        flag = true;
        //告诉吃货 现在能吃了 唤醒他
        this.notifyAll();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public synchronized void eatFood() {
    try {
        while (!flag) { //判断食物的状态 如果为false 说明餐桌上没食物 让吃货先等一下
            this.wait();
        }
        //如果flag为true 说明有食物 吃货可以去吃了
        System.out.println(Thread.currentThread().getName() + "做了第" + count + "个包子");
        flag = false;//吃完东西了 把食物的状态改变一下 说明已经吃完了 然后去叫厨子让做菜
        this.notifyAll(); //唤醒厨子 该做饭了 东西吃完了
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

}
生产者类

public class ProducerRun implements Runnable {
private Desk desk ;

public ProducerRun(Desk desk) {
    this.desk = desk;
}

@Override
public void run() {
    while (true) {
        desk.makeFood();
    }
}

}
消费者类

 public class ConsumerRun implements Runnable{
private Desk desk;
public ConsumerRun(Desk desk) {
    this.desk = desk;
}

@Override
public void run() {
    //以为要执行多次 所以用了死循环
    while (true){
        desk.eatFood();
    }
}

}

利用Lock锁和Condition解决(方法二)

public class Desk {
private Integer count=0;
private Boolean flag=false;
private final Lock LOCK =new ReentrantLock();
private final Condition PRODUCER_CONDITION=LOCK.newCondition();
private final Condition CONSUMER_CONDITION=LOCK.newCondition();
//生产者  用lock锁 必须用try catch finall 不然中途出现异常程序会停止
public void makeFood(){
    try {
        LOCK.lock();
        while (flag){ //如果状态为ture 说明现在有餐桌上面有东西 厨子这个线程应该去等待
            PRODUCER_CONDITION.await(); 
        }
        count++; // 说明现在餐桌上没食物  厨子该去做食物
        System.out.println(Thread.currentThread().getName()+"做了第"+count+"个包子");
        flag=true; //厨子做好了 用一个状态标记下已经做好了 方面吃货能做出判断 知道东西做好了 可以吃了
        CONSUMER_CONDITION.signal(); //唤醒吃货 能吃了 
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        LOCK.unlock();
    }
}
public void eatFood(){
    try {
        LOCK.lock();
        while (!flag){ //判断食物的状态 如果为false 说明餐桌上没食物 让吃货先等一下
            CONSUMER_CONDITION.await();
        }
        //如果flag为true 说明有食物 吃货可以去吃了
        System.out.println(Thread.currentThread().getName()+"做了第"+count+"个包子");
        flag=false; //吃完东西了 把食物的状态改变一下 说明已经吃完了 然后去叫厨子让做菜
        PRODUCER_CONDITION.signal();//唤醒厨子 该做饭了 现在
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        LOCK.unlock();
    }
}

}
//生成者类

public class PruducerRun implements Runnable{
private Desk desk;

public PruducerRun(Desk desk) {
    this.desk = desk;
}

@Override
public void run() {
    while (true){
        desk.makeFood();
    }
}

}
//消费者类

  public class ConsumerRun implements Runnable{
 private Desk desk;

public ConsumerRun(Desk desk) {
    this.desk = desk;
}

@Override
public void run() {
    while (true){
        desk.eatFood();
    }
}

}
测试类 共有的

public class Test {
public static void main(String[] args) {
  Desk desk=new Desk();
    ConsumerRun consumerRun=new ConsumerRun(desk);
   PruducerRun producerRun=new PruducerRun(desk);
    Thread t1 =new Thread(consumerRun,"吃货");
    Thread t2 =new Thread(consumerRun,"吃货");
    Thread t3 =new Thread(consumerRun,"吃货");
    Thread t4 =new Thread(producerRun,"厨子");
    Thread t5 =new Thread(producerRun,"厨子");
    Thread t6 =new Thread(producerRun,"厨子");
   t1.start();
   t2.start();
   t3.start();
   t4.start();
   t5.start();
   t6.start();
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值