JAVA线程同步——消费者和生产者模式

场景介绍

我们有一个数据缓冲区,一个或者多个生产者把数据存入这个缓冲区,一个或者多个消费者从缓冲区中取出数据
缓冲区中的是共享数据
当缓冲区满的时候不能生产者将不能再放入数据到缓冲区(生产者线程阻塞)
当缓冲区空的时候消费者不能从缓冲区中读取数据(消费者线程阻塞)

实例:
1. 创建数据处理类,其中缓冲区的保存、读取、生产操作
public class EventStorage {

    //缓冲区数据的最大值
    private int maxSize;
    //缓冲区
    private List<Date> storage;

    public EventStorage() {
        maxSize = 10;
        storage = new LinkedList<>();
    }

    //生产方法
    public synchronized void set() {
        //如果已满就挂起线程
        while (storage.size() == maxSize) {
            try {
                System.out.println("producer wait");
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        storage.add(new Date());
        System.out.println("Set : " + storage.size());
        //通知等待的线程消费者线程
        notifyAll();
    }

    //消费方法
    public synchronized void get() {
        //如果没有库存就挂起线程
        while (storage.size() == 0) {
            try {
                System.out.println("consumer wait");
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        ((LinkedList<?>) storage).poll();
        System.out.println("Get : " + storage.size());
        //通知阻塞的线程生产者线程
        notifyAll();
    }


}

2. 创建生产者线程,其构造函数接收一个数据处理对象
public class EventProducer implements Runnable {

    private EventStorage storage;

    public EventProducer(EventStorage storage) {
        this.storage = storage;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            storage.set();
        }
    }

}

3.创建消费者线程,也接收同一个数据处理对象
public class EventConsumer implements Runnable {

    private EventStorage storage;

    public EventConsumer(EventStorage storage) {
        this.storage = storage;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            storage.get();
        }
    }

}

4.创建测试类
public class TestCP {

    public static void main(String[] args) {
        EventStorage storage = new EventStorage();

        Thread consumer = new Thread(new EventConsumer(storage));
        Thread producer = new Thread(new EventProducer(storage));

        consumer.start();
        producer.start();

    }

}

5.运行程序查看控制台输出


可以看到程序输出和预期的结果一样

注意:
1.必须在while()循环内调用wait(),使得线程在达到指定条件后跳出循环等待才继续运行
2.数据处理类的生产和消费方法是synchronized修饰的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值