JavaEE线程安全的生产者消费者模型优点

本文介绍了Java中的阻塞队列 BlockingQueue,它是一个线程安全且具备先进先出特性的数据结构。当队列为空时,尝试取元素会阻塞,直到有元素加入;队列满时,尝试添加元素同样会阻塞,直至队列有空位。通过示例展示了如何使用LinkedBlockingQueue创建阻塞队列,并实现了一个简单的生产者消费者模型。该模型有助于解耦合系统并平滑处理高并发请求。此外,还给出了自定义阻塞队列MyBlockingQueue的实现,包括入队、出队操作以及同步锁的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

阻塞队列

定义:
1)符合先进先出的队列
2)线程安全
3)产生阻塞效果
如果队列为空,尝试出队列就会出现阻塞,阻塞到队列不为空为止
如果队列为满,尝试入队列也会出现阻塞,阻塞到队列不为满为止

BlockingQueue<String> queque = new LinkedBlockingQueue<>();
queue.put("hello");
String s = queue.take();

生产者消费者模型

优点:
1.解耦合
2.能够对请求削峰填谷

实际开发中使用到的“阻塞队列”并不是一个简单的数据结构了,而是一个/一组专门的服务器程序,提供的功能也不仅仅是阻塞队列的功能还有数据持久化存储,支持多个数据通道…,这样的队列被称为消息队列

总结生产者消费者模型:
1.直接对方法加锁
2.队列为满或者为空时阻塞
3.放入获取出队列
4.唤醒对应等待

class MyBlockingQueue{
    //保存数据的本体
    private int[] data = new int[1000];
    //有效元素个数
    private int size = 0;
    //队首元素下标
    private int head = 0;
    //队尾下标
    private int tail = 0;

    //专门的锁对象
    private Object locker  = new Object();

    //入队列
    public void put(int value) throws InterruptedException {
        synchronized (locker){
            if(size == data.length){
                //队列满了,等待
                locker.wait();
            }
            //把新的元素放到tail位置上
            data[tail] = value;
            tail++;
            if(tail >= data.length){
                tail = 0;
            }
            size++;
            //如果入队成功,则队列非空,于是就唤醒take中的阻塞等待
            locker.notify();
        }

    }

    public Integer take() throws InterruptedException {
        synchronized (locker){
            if(size == 0){
                //如果队列为空就阻塞
                locker.wait();
            }
            //取出head位置的元素
            int ret = data[head];
            head++;
            if(head >= data.length){
                head = 0;
            }
            size--;
            //take成功之后,就唤醒put中的等待
            locker.notify();
            return ret;
        }
    }
}
public class 生产者消费者模型 {
    private static MyBlockingQueue queue = new MyBlockingQueue();

    public static void main(String[] args) {
        Thread producer = new Thread(() -> {
            int num = 0;
            while(true){
                try {
                    System.out.println("生产了:" + num);
                    queue.put(num);
                    num++;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        producer.start();

        Thread customer = new Thread(() ->{
            while(true){
                try {
                    int num = queue.take();
                    System.out.println("消费了:" + num);
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        customer.start();
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值