数据结构学习网站:
思维导图:
阻塞队列介绍
1.1 队列
1.是限定在一端进行插入,另一端进行删除的特殊线性表。
2.先进先出(FIFO)线性表。
3.允许出队的一端称为队头,允许入队的一端称为队尾。
![](https://i-blog.csdnimg.cn/blog_migrate/07691aa47293a612a1bb04709e5e1038.png)
Queue接口
public interface Queue<E> extends Collection<E> {
//添加一个元素,添加成功返回true, 如果队列满了,就会抛出异常
boolean add(E e);
//添加一个元素,添加成功返回true, 如果队列满了,返回false
boolean offer(E e);
//返回并删除队首元素,队列为空则抛出异常
E remove();
//返回并删除队首元素,队列为空则返回null
E poll();
//返回队首元素,但不移除,队列为空则抛出异常
E element();
//获取队首元素,但不移除,队列为空则返回null
E peek();
}
1.2 阻塞队列(BlockingQueue)
阻塞队列 (BlockingQueue)是Java util.concurrent包下重要的数据结构,BlockingQueue提供了线程 安全的队列访问方式:
当阻塞队列插入数据时,如果队列已满,线程将会阻塞等待直到队列非满;从
阻塞队列取数据时,如果队列已空,线程将会阻塞等待直到队列非空。
并发包下很多高级同步类的实 现都是基于BlockingQueue实现的。
BlockingQueue接口
![](https://i-blog.csdnimg.cn/blog_migrate/dfd98032860aff8920d17cfa3b2340f3.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1358e94bd76397da091b91f752a2207e.png)
应用场景:
阻塞队列在实际应用中有很多场景,以下是一些常见的应用场景:
1.线程池
线程池中的任务队列通常是一个阻塞队列。当任务数超过线程池的容量时,新提交的任务将被放入任务队列中等待执行。线程池中的工作线程从任务队列中取出任务进行处理,如果队列为空,则工作线程会被阻塞,直到队列中有新的任务被提交
线程池中的任务队列通常是一个阻塞队列。当任务数超过线程池的容量时,新提交的任务将被放入任务队列中等待执行。线程池中的工作线程从任务队列中取出任务进行处理,如果队列为空,则工作线程会被阻塞,直到队列中有新的任务被提交
2.生产者-消费者模型
在生产者-消费者模型中,生产者向队列中添加元素,消费者从队列中取出元素进行处理。阻塞队列可以很好地解决生产者和消费者之间的并发问题,避免线程间的竞争和冲突。
在生产者-消费者模型中,生产者向队列中添加元素,消费者从队列中取出元素进行处理。阻塞队列可以很好地解决生产者和消费者之间的并发问题,避免线程间的竞争和冲突。
![](https://i-blog.csdnimg.cn/blog_migrate/f83cf0de18b27f169f9537285758a1d8.png)
3.消息队列
消息队列使用阻塞队列来存储消息,生产者将消息放入队列中,消费者从队列中取出消息进行处理。消息队列可以实现异步通信,提高系统的吞吐量和响应性能,同时还可以将不同的组件解糟,提高系统的可维护性和可扩展性。
4.缓存系统
缓存系统使用阻塞队列来存储缓存数据,当缓存数据被更新时,它会被放入队列中,其他线程可以从队列中取出最新的数据进行使用。使用阻塞队列可以避免并发更新缓存数据时的竞争和冲突
5.并发任务处理
在并发任务处理中,可以将待处理的任务放入阻塞队列中,多个工作线程可以从队列中取出任务进行处理。使用阻塞队列可以避免多个线程同时处理同一个任务的问题,并且可以将任务的提交和执行解羯,提高系统的可维护性和可扩展性。
总之,阻塞队列在实际应用中有很多场景,它可以帮助我们