Java并发——阻塞队列的实现

1.使用场景

阻塞的应用场景,比如 生产-消费模式,限流统计等等。什么 ArrayBlockingQueue、LinkedBlockingQueue、DelayQueue 等等,都是阻塞队列的实现。

但是我们发现其使用目的和消息队列类似,实际上是的,只是阻塞队列是用于单个系统的消息传递,生产者消费者模式,而消息队列一般是分布式系统间的生产者消费者模式,但无论是哪种形式,其实现都离不开基本的多线程同步编程模式。

2.实现原理

阻塞队列(BlockingQueue)是一个接口,其具体实现分为如下几种,包括ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue等等。

  • ArrayBlockingQueue:从名称上就可以知道ArrayBlockingQueue底层是以数组模拟实现的,既然以数组模拟,其动态扩展便不方便,因此适合做有界队列,需要在创建时就指定最大容量。
  • LinkedBlockingQueue:以链表模拟实现,由于是链表,扩展方便,因此适合做无界队列。

下面讲一下最主要的阻塞的实现,阻塞在于:队列为空时取元素,则线程阻塞;队列满时加元素,则线程阻塞。而对于这种生产者消费者模式,其实最方便的便是使用 锁+多个条件变量 来实现。

自然而然想到需要两个条件变量:notEmpty(队列空,取元素时,一直阻塞在notEmpty上),notFull(队列满,添加元素,则一直阻塞在notFull上)。

下面贴上队列空时的编码过程:

final ReentranLock lock;
final Condition notEmpty;
final Condition notFull;

public E take() throw InterruptedException{
	final ReentranLock lcok = this.lock;
	lock.lockIntereruptibly();
	try{
		while(count==0){
			notEmpty.await();
		}
		return extract();
	}finally{
		lock.unlock();
	}
}
发布了69 篇原创文章 · 获赞 10 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/JustKian/article/details/104206878