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

阻塞队列

定义:
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();
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值