多线程实例三----多生产者多消费者(模拟kfc多生产和多消费)

KFC中,同时有多个产者生产汉堡,也有多个消费者消费汉堡,当生产到100个剩余时,就暂停生产;当销售到0个时,就暂停销售。此例子就是简单的多生产和多消费问题,跟有些多生产多消费例子不同的是其他的基本上是生产一个汉堡就唤醒消费者消费,生成一个消费一个;而在本例子中生产者和消费者则互不影响,只是达到设置的极限条件之后才唤醒。

本例子使用了三种实现方式,分别为简单多线程实现、用线程池实现、用jdk1.5新特性Lock和Condition实现。

1、简单多线程实现

package com.shone.thread.KFC;

/**
 * Created by Xiao GuoJian on 2018/1/24.
 * 在一个KFC内,服务员负责生产食物,消费者负责消费食物;
 * 当生产到一定数量可以休息一下,直到消费完食物,再马上生产,一直循环
 */

class Food{
    public int count = 1;//默认数量
    public int maxCount = 20;//count为100时,生产者停止生产

    //生产
    public synchronized void product(){
        while(count>=maxCount){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        count++;
        try {
            Thread.sleep(25);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+" 生产一个汉堡,当前汉堡数:"+count);

        if(count == maxCount){
            notifyAll();
        }
    }

    //消费
    public synchronized void consume(){
        while(count <= 0){
            try {
                wait();//当前线程等待
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        count--;
        try {
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+" 消费一个汉堡,当前汉堡数:"+count);
        if(count==0){
            notifyAll();
        }
    }
}

//生产者
class Producter extends Thread{
    private Food food;
    public Producter(Food food){
        super();
        this.food = food;
    }

    public void run(){
        while (true){
            food.product();
        }
    }
}

//消费者
class Consumer extends Thread{
    private Food food;
    public Consumer(Food food){
        super();
        this.food = food;
    }

    public void run(){
        while (true){
            food.consume();
        }
    }
}


public class KfcDemo {
    public static void main(String[] args) {
        Food food = new Food();

        Producter producter1 = new Producter(food);
        Producter producter2 = new Producter(food);
        Consumer consumer1 = new Consumer(food);
        Consumer consumer2 = new Consumer(food);
        producter1.start();
        producter2.start();
        consumer1.start();
        consumer2.start();
    }
}

2、用线程池实现

package com.shone.thread.KFCwithPool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by Xiao GuoJian on 2018/1/24.
 * 在一个KFC内,服务员负责生产食物,消费者负责消费食物;
 * 当生产到一定数量可以休息一下,直到消费完食物,再马上生产,一直循环
 *
 * 用线程池的方式实现多生产多消费
 */

class Food{
    public int count = 1;//默认数量
    public int maxCount = 20;//count为100时,生产者停止生产

    //生产
    public synchronized void product(){
        while(count>=maxCount){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        count++;
        try {
            Thread.sleep(25);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+" 生产一个汉堡,当前汉堡数:"+count);

        if(count == maxCount){
            notifyAll();
        }
    }

    //消费
    public synchronized void consume(){
        while(count <= 0){
            try {
                wait();//当前线程等待
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        count--;
        try {
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+" 消费一个汉堡,当前汉堡数:"+count);
        if(count==0){
            notifyAll();
        }
    }
}

//生产者
class Producter implements Runnable{
    private Food food;
    public Producter(Food food){
        super();
        this.food = food;
    }

    public void run(){
        while (true){
            food.product();
        }
    }
}

//消费者
class Consumer implements Runnable{
    private Food food;
    public Consumer(Food food){
        super();
        this.food = food;
    }

    public void run(){
        while (true){
            food.consume();
        }
    }
}


public class KfcDemo {
    public static void main(String[] args) {
        Food food = new Food();

        Producter producter1 = new Producter(food);
        Producter producter2 = new Producter(food);
        Consumer consumer1 = new Consumer(food);
        Consumer consumer2 = new Consumer(food);

        ExecutorService pool = Executors.newCachedThreadPool();
        pool.execute(producter1);
        pool.execute(producter2);
        pool.execute(consumer1);
        pool.execute(consumer2);
    }
}
3、用jdk1.5新特性Lock和Condition实现

package com.shone.thread.KFCLock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by Xiao GuoJian on 2018/1/24.
 * 在一个KFC内,服务员负责生产食物,消费者负责消费食物;
 * 当生产到一定数量可以休息一下,直到消费完食物,再马上生产,一直循环
 *
 * 用Lock 和 Condition实现
 * 这样的好处是更灵活,可以分开控制是生产者和消费者
 */

class Food{
    public int count = 1;//默认数量
    public int maxCount = 20;//count为100时,生产者停止生产

    Lock lock =  new ReentrantLock();//创建锁
    Condition pro_ = lock.newCondition();//生产者锁条件(监视器)对象
    Condition con_ = lock.newCondition();//消费者锁条件(监视器)对象

    //生产
    public void product(){
        lock.lock();//获得锁
        try{
            while(count>=maxCount){
                try {
                    pro_.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            count++;
            try {
                Thread.sleep(25);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" 生产一个汉堡,当前汉堡数:"+count);

            if(count == maxCount){
                con_.signalAll();
            }
        } finally {
            lock.unlock();
        }

    }

    //消费
    public void consume(){
        lock.lock();
        try{
            while(count <= 0){
                try {
                    con_.await();//当前线程等待
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            count--;
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" 消费一个汉堡,当前汉堡数:"+count);
            if(count==0){
                pro_.signalAll();
            }
        } finally {
            lock.unlock();
        }

    }
}

//生产者
class Producter extends Thread{
    private Food food;
    public Producter(Food food){
        super();
        this.food = food;
    }

    public void run(){
        while (true){
            food.product();
        }
    }
}

//消费者
class Consumer extends Thread{
    private Food food;
    public Consumer(Food food){
        super();
        this.food = food;
    }

    public void run(){
        while (true){
            food.consume();
        }
    }
}


public class KfcDemo {
    public static void main(String[] args) {
        Food food = new Food();

        Producter producter1 = new Producter(food);
        Producter producter2 = new Producter(food);
        Consumer consumer1 = new Consumer(food);
        Consumer consumer2 = new Consumer(food);
        producter1.start();
        producter2.start();
        consumer1.start();
        consumer2.start();
    }
}




  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值