阻塞队列实现原理

21 篇文章 1 订阅
7 篇文章 0 订阅

1.阻塞队列实现原理
阻塞队列与普通队列的区别在于,阻塞队列提供了可阻塞的put和take方法。如果队列是空的,消费者使用take方法从队列中获取数据就会被阻塞,直到队列有数据可用;当队列是满的,生产者使用put方法向队列里添加数据就会被阻塞,直到队列中数据被消费有空闲位置可用
生产消费模式阻塞队列
2.JUC提供了7种适合与不同应用场景的阻塞队列。
1)ArrayBlockingQueue:基于数组实现的有界阻塞队列。
2)LinkedBlockingQueue:基于链表实现的有界阻塞队列。
3)PriorityBlockingQueue:支持按优先级排序的无界阻塞队列。
4)DelayQueue:优先级队列实现的无界阻塞队列。
5)SynchronousQueue:不存储元素的阻塞队列。
6)LinkedTransferQueue:基于链表实现的无界阻塞队列。
7)LinkedBlockingDeque:基于链表实现的双向无界阻塞队列。
7个阻塞队列全部实现了BlockingQueue接口,插入和移除元素分别各提供了4种处理方式。

插入操作:添加元素到队列中。
1)add(e):当队列满的时候,继续插入元素会抛出IllegalStateException("Queue full")异常。
2)offer(e):当队列满的时候,继续插入元素不会阻塞,直接返回false。如果插入成功则返回true。
3)put(e):当队列满的时候,继续插入元素线程会被一直阻塞直到队列有空闲位置可用时为止。
4)offer(e,time,unit):当队列满的时候,调用该方法的线程会被阻塞一段时间,如果超过指定时间还未添加成功,线程直接退出。

移除操作:从队列中移除元素。
1)remove():当队列为空时,调用该方法元素会抛出NoSuchElementException异常。2)poll():当队列为空时,调用该方法不会阻塞,直接返回null。当队列不为空时,则从队列中取出一个元素。
3)take():当队列为空时,调用该方法会被一直阻塞直到队列有数据可用时为止。
4)poll(time,unit):当队列为空时,调用该方法的线程会被阻塞一段时间,如果超过指定时间队列仍没有数据可用,直接返回null。当然,如果是向无界阻塞队列中插入元素,因为无界队列永远不可能会出现满的情况,所以使用put或offerr(e,time,unit)方法永远不会被阻塞。
ArrayBlockingQueue和LinkedBlockingQueue是最常用的阻塞队列,一般情况下,这两个类基本上能满足大部分的LinkedBlockingQueue和ArrayBlockingQueue两个队列的主要区别如下。
1)底层数据结构不同。ArrayBlockingQueue基于数组实现,使用数组存储元素。LinkedBlockingQueue基于单链表实现,使用链表存储元素。
2)队列容量不同。ArrayBlockingQueue构造时必须指定容量,且后续不能改变。LinkedBlockingQueue既可以指定大小,也可以不指定,默认使用一个类似无界的容量(Integer. MAX_VALUE)。
3)ArrayBlockingQueue可以使用公平/非公平锁策略,而LinkedBlockingQueue只能使用非公平策略。ArrayBlockingQueue入队和出队公用一把全局ReentrantLock锁;LinkedBlockingQueue出队和入队分别使用独立的锁,所以LinkedBlockingQueue的并发性能要比ArrayBlockingQueue好生产者和消费者场景的需要

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java阻塞队列是一种线程安全的数据结构,它提供了同步的功能,用于在多线程环境中安全地进行数据交换和通信。其实现原理主要涉及以下几个方面。 首先,阻塞队列的实现会使用锁机制确保线程安全。Java中可以使用ReentrantLock或synchronized关键字来实现锁,在对队列进行操作时会对其进行加锁,保证同一时刻只有一个线程能够访问队列。 其次,阻塞队列内部会使用条件变量或信号量来实现线程间的协调与通信。当队列为空时,消费者线程需要等待直到队列有数据可取;当队列已满时,生产者线程需要等待直到队列有空位置可放入新数据。通过条件变量或信号量的等待和唤醒机制,实现了线程间的同步和互斥。 此外,阻塞队列通常还会使用一个循环数组来存储数据。循环数组在插入和删除元素时能够高效地利用已分配的内存空间,避免了频繁的扩容和内存拷贝。同时,循环数组的读写指针可以通过取模运算得到,实现环形循环。 最后,阻塞队列还会根据不同的需求提供不同的阻塞操作。例如,用于插入元素的put()方法在队列已满时会阻塞直到有空位置可用,用于获取元素的take()方法在队列为空时会阻塞直到有数据可取。这些阻塞操作的实现依赖于同步和协调机制,保证了线程安全和数据一致性。 总之,Java阻塞队列通过使用锁、条件变量或信号量、循环数组等机制,实现了线程安全和线程间的同步与通信。它是多线程编程中常用的工具,能够有效地管理数据的生产和消费,提高多线程程序的可靠性和性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值