生产者与消费者

Posted Geek

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了生产者与消费者相关的知识,希望对你有一定的参考价值。

在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。

在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式

生产者与消费者模式是通过一个容器来解决生产者与消费者的强耦合关系,生产者与消费者之间不直接进行通讯,而是利用阻塞队列来进行通讯,生产者生成数据后直接丢给阻塞队列,消费者需要数据则从阻塞队列获取,实际应用中,生产者与消费者模式则主要解决生产者与消费者生产与消费的速率不一致的问题,达到平衡生产者与消费者的处理能力,而阻塞队列则相当于缓冲区。

具体实现:消费者生产苹果放到篮子里,消费者从篮子里取出苹果

篮子类相当于缓冲区:


public
class Basket { private List<Apple> list = new ArrayList<>(); public void put(Apple apple) { while (list.size() == 10) { try { synchronized (this) { this.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } } synchronized (this) { list.add(apple); System.out.println(Thread.currentThread().getName() + "开始生产苹果 "+apple.getName()+"当前苹果个数为:" + list.size()); this.notify(); } } public void get() { while (list.size() == 0) { try { synchronized (this) { this.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } } synchronized (this) { Apple apple = list.get(list.size() - 1); list.remove(apple); System.out.println( Thread.currentThread().getName() + "取出苹果" + apple.getName() + "当前剩余" + list.size() + "个苹果"); this.notify(); } } }

苹果类:

public class Apple {
    private String name;
    public void setName(String name) {
        this.name=name;
    }
    public String getName() {
        return name;
    }

}

生产者线程:

public class Producer extends Thread {
    private Basket basket;

    public Producer(Basket basket) {
        super();
        this.basket = basket;
    }

    @Override
    public void run() {  //生产苹果
        for (int i = 1; i <=20; i++) {
            Apple apple = new Apple();
            apple.setName(String.valueOf(i));
            this.basket.put(apple);
        }
    }

}

消费者线程:

public class Consumer extends Thread {
    private Basket basket;

    public Consumer(Basket basket) {
        super();
        this.basket = basket;
    }

    @Override
    public void run() { //消费苹果
        for (int i = 0; i < 20; i++) {
            this.basket.get();
        }
    }

}

测试类:

 

public class Test {
    public static void main(String[] args) {
        Basket basket = new Basket();
        Producer producer = new Producer(basket);
        Consumer consumer = new Consumer(basket);
        producer.setName("生产者");
        consumer.setName("消费者");
         producer.start();
         
         consumer.start();
         
         
    }
}

 运行效果为:

生产者开始生产苹果 1当前苹果个数为:1
生产者开始生产苹果 2当前苹果个数为:2
生产者开始生产苹果 3当前苹果个数为:3
生产者开始生产苹果 4当前苹果个数为:4
生产者开始生产苹果 5当前苹果个数为:5
生产者开始生产苹果 6当前苹果个数为:6
生产者开始生产苹果 7当前苹果个数为:7
生产者开始生产苹果 8当前苹果个数为:8
生产者开始生产苹果 9当前苹果个数为:9
生产者开始生产苹果 10当前苹果个数为:10
消费者取出苹果10当前剩余9个苹果
消费者取出苹果9当前剩余8个苹果
消费者取出苹果8当前剩余7个苹果
消费者取出苹果7当前剩余6个苹果
生产者开始生产苹果 11当前苹果个数为:7
消费者取出苹果11当前剩余6个苹果
消费者取出苹果6当前剩余5个苹果
消费者取出苹果5当前剩余4个苹果
消费者取出苹果4当前剩余3个苹果
消费者取出苹果3当前剩余2个苹果
消费者取出苹果2当前剩余1个苹果
消费者取出苹果1当前剩余0个苹果
生产者开始生产苹果 12当前苹果个数为:1
生产者开始生产苹果 13当前苹果个数为:2
生产者开始生产苹果 14当前苹果个数为:3
生产者开始生产苹果 15当前苹果个数为:4
生产者开始生产苹果 16当前苹果个数为:5
生产者开始生产苹果 17当前苹果个数为:6
生产者开始生产苹果 18当前苹果个数为:7
生产者开始生产苹果 19当前苹果个数为:8
生产者开始生产苹果 20当前苹果个数为:9
消费者取出苹果20当前剩余8个苹果
消费者取出苹果19当前剩余7个苹果
消费者取出苹果18当前剩余6个苹果
消费者取出苹果17当前剩余5个苹果
消费者取出苹果16当前剩余4个苹果
消费者取出苹果15当前剩余3个苹果
消费者取出苹果14当前剩余2个苹果
消费者取出苹果13当前剩余1个苹果
消费者取出苹果12当前剩余0个苹果

以上是关于生产者与消费者的主要内容,如果未能解决你的问题,请参考以下文章

请问如何用C语言实现“生产者与消费者问题”?(最好附上完整的C语言源代码)

JAVA模拟生产者与消费者实例

java面试笔试题代码,先收藏了

生产者与消费者案例-虚假唤醒

使用java代码连接不上kafka的解决方案(生产者与消费者都没能连上)

浅谈Java简单实现的生产者与消费者问题