Java生产者消费者问题

一、Java生产者消费者问题

线程间协作的一个经典问题:生产者消费者

生产者生产产品,消费者消费产品。
当缓冲区满时:生产者暂停生产;当缓冲区空时:消费者停止消费。

ProducerAndConsumer.java

两个线程,一个生产者线程,一个消费者线程
生产者生产100个坤坤,消费者消费100个坤坤。缓冲区大小为10。

package com.peng.sync;

// 线程间协作,管程法解决生产者消费者问题
// 生产者,消费者,产品,缓冲区
public class ProcucerAndConsumer {
    public static void main(String[] args) {
        SynContainer container = new SynContainer();
        Producer producer = new Producer(container);
        Consumer consumer = new Consumer(container);

        new Thread(producer).start();
        new Thread(consumer).start();
    }
}
// 生产者
class Producer implements Runnable{
    SynContainer container;
    public Producer(SynContainer c){
        this.container = c;
    }
    @Override
    public void run() {
        for (int i = 0; i < 100; i++){
            try {
                container.push(new Chicken(i));
                if (i == 70){
                    Thread.sleep(200);
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
// 消费者
class Consumer implements Runnable{
    SynContainer container;
    public Consumer(SynContainer c){
        this.container =c;
    }
    @Override
    public void run() {
        for (int i = 0; i < 100; i++){
            try {
                Chicken chicken = container.pop();
                if (i == 30){
                    Thread.sleep(200);
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
// 产品
class Chicken{
    int id;

    public Chicken(int id) {
        this.id = id;
    }  
}
// 缓冲区
class SynContainer{
    // 缓冲区大小,可存放10个产品
    Chicken[] chickens = new Chicken[10];
    // 存放的产品数目,开始为0
    static int count = 0;

    // 存放产品
    public synchronized void push(Chicken c) throws InterruptedException{
        // 如果缓冲区满了,则等待
        while (count == chickens.length){
            System.out.println("缓冲区已满,暂停生产");
            this.wait();
        }
        chickens[count] = c;
        System.out.println("生产了第" + c.id + "只鸡");
        count++;
        this.notify();
    }
    // 取出产品
    public synchronized Chicken pop() throws InterruptedException{
        // 如果缓冲区为0,则等待
        while (count == 0){
            System.out.println("缓冲区为0,暂停消费");
            this.wait();
        }
        count--;
        Chicken c1 = chickens[count];
        System.out.println("消费了第" + c1.id + "只鸡");
        notifyAll();
        return c1;
    }
}

执行结果如下:
注意

缓冲区为0,暂停消费
生产了第0只鸡
生产了第1只鸡
生产了第2只鸡
生产了第3只鸡
生产了第4只鸡
生产了第5只鸡
生产了第6只鸡
生产了第7只鸡
生产了第8只鸡
生产了第9只鸡
消费了第9只鸡
消费了第8只鸡
消费了第7只鸡
消费了第6只鸡
消费了第5只鸡
消费了第4只鸡
消费了第3只鸡
消费了第2只鸡
消费了第1只鸡
消费了第0只鸡
缓冲区为0,暂停消费
生产了第10只鸡
生产了第11只鸡
生产了第12只鸡
生产了第13只鸡
生产了第14只鸡
生产了第15只鸡
生产了第16只鸡
生产了第17只鸡
生产了第18只鸡
生产了第19只鸡
缓冲区已满,暂停生产
消费了第19只鸡
消费了第18只鸡
消费了第17只鸡
消费了第16只鸡
消费了第15只鸡
消费了第14只鸡
消费了第13只鸡
消费了第12只鸡
消费了第11只鸡
消费了第10只鸡
缓冲区为0,暂停消费
生产了第20只鸡
生产了第21只鸡
生产了第22只鸡
生产了第23只鸡
生产了第24只鸡
生产了第25只鸡
生产了第26只鸡
生产了第27只鸡
生产了第28只鸡
生产了第29只鸡
缓冲区已满,暂停生产
消费了第29只鸡
消费了第28只鸡
消费了第27只鸡
消费了第26只鸡
消费了第25只鸡
消费了第24只鸡
消费了第23只鸡
消费了第22只鸡
消费了第21只鸡
消费了第20只鸡
缓冲区为0,暂停消费
生产了第30只鸡
生产了第31只鸡
生产了第32只鸡
生产了第33只鸡
生产了第34只鸡
生产了第35只鸡
生产了第36只鸡
生产了第37只鸡
生产了第38只鸡
生产了第39只鸡
缓冲区已满,暂停生产
消费了第39只鸡
生产了第40只鸡
缓冲区已满,暂停生产
消费了第40只鸡
消费了第38只鸡
消费了第37只鸡
消费了第36只鸡
消费了第35只鸡
消费了第34只鸡
消费了第33只鸡
消费了第32只鸡
消费了第31只鸡
消费了第30只鸡
缓冲区为0,暂停消费
生产了第41只鸡
生产了第42只鸡
生产了第43只鸡
生产了第44只鸡
生产了第45只鸡
生产了第46只鸡
生产了第47只鸡
生产了第48只鸡
生产了第49只鸡
生产了第50只鸡
缓冲区已满,暂停生产
消费了第50只鸡
消费了第49只鸡
消费了第48只鸡
消费了第47只鸡
消费了第46只鸡
消费了第45只鸡
消费了第44只鸡
消费了第43只鸡
消费了第42只鸡
消费了第41只鸡
缓冲区为0,暂停消费
生产了第51只鸡
生产了第52只鸡
生产了第53只鸡
生产了第54只鸡
生产了第55只鸡
生产了第56只鸡
生产了第57只鸡
生产了第58只鸡
生产了第59只鸡
生产了第60只鸡
缓冲区已满,暂停生产
消费了第60只鸡
消费了第59只鸡
消费了第58只鸡
消费了第57只鸡
消费了第56只鸡
消费了第55只鸡
消费了第54只鸡
消费了第53只鸡
消费了第52只鸡
消费了第51只鸡
缓冲区为0,暂停消费
生产了第61只鸡
生产了第62只鸡
生产了第63只鸡
生产了第64只鸡
生产了第65只鸡
生产了第66只鸡
生产了第67只鸡
生产了第68只鸡
生产了第69只鸡
生产了第70只鸡
消费了第70只鸡
消费了第69只鸡
消费了第68只鸡
消费了第67只鸡
消费了第66只鸡
消费了第65只鸡
消费了第64只鸡
消费了第63只鸡
消费了第62只鸡
消费了第61只鸡
缓冲区为0,暂停消费
生产了第71只鸡
生产了第72只鸡
生产了第73只鸡
生产了第74只鸡
生产了第75只鸡
生产了第76只鸡
生产了第77只鸡
生产了第78只鸡
生产了第79只鸡
生产了第80只鸡
缓冲区已满,暂停生产
消费了第80只鸡
消费了第79只鸡
消费了第78只鸡
消费了第77只鸡
消费了第76只鸡
消费了第75只鸡
消费了第74只鸡
消费了第73只鸡
消费了第72只鸡
消费了第71只鸡
缓冲区为0,暂停消费
生产了第81只鸡
生产了第82只鸡
生产了第83只鸡
生产了第84只鸡
生产了第85只鸡
生产了第86只鸡
生产了第87只鸡
生产了第88只鸡
生产了第89只鸡
生产了第90只鸡
缓冲区已满,暂停生产
消费了第90只鸡
消费了第89只鸡
消费了第88只鸡
消费了第87只鸡
消费了第86只鸡
消费了第85只鸡
消费了第84只鸡
消费了第83只鸡
消费了第82只鸡
消费了第81只鸡
缓冲区为0,暂停消费
生产了第91只鸡
生产了第92只鸡
生产了第93只鸡
生产了第94只鸡
生产了第95只鸡
生产了第96只鸡
生产了第97只鸡
生产了第98只鸡
生产了第99只鸡
消费了第99只鸡
消费了第98只鸡
消费了第97只鸡
消费了第96只鸡
消费了第95只鸡
消费了第94只鸡
消费了第93只鸡
消费了第92只鸡
消费了第91只鸡

二、线程池

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

// 使用ExecutorService和Executors创建线程池
public class TestThreadPool {
    public static void main(String[] args) {
        ExecutorService service = Executors.newFixedThreadPool(5);
        Pools p1 = new Pools();
        Pools p2 = new Pools();
        Pools p3 = new Pools();
        Pools p4 = new Pools();

        service.execute(p1);
        service.execute(p2);
        service.execute(p3);
        service.execute(p4);
        // 关闭
        service.shutdown();
    }
}

class Pools implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值