深入理解Java系列

您所在的位置:网站首页 线程阻塞什么意思 深入理解Java系列

深入理解Java系列

2024-02-12 00:48| 来源: 网络整理| 查看: 265

本文已参与掘金创作者训练营第三期「高产更文」赛道,详情查看:掘力计划|创作者训练营第三期正在进行,「写」出个人影响力。

Hi 大家好,我是「毛与帆」,一个热爱技术的后端工程师,感谢你的关注!

欢迎来到 深入理解Java系列 文章,本系列文章主要目的是重温Java中的基础概念、数据结构、多线程、锁、JUC等重点知识点。

在上一篇文章深入理解Java系列 | Queue用法详解中,我们一起研究了Java中Queue接口的用法和基本原理。我们知道,LinkedList实现的队列功能是非线程安全的,如果在多个线程进行入队和出队操作,将会产生数据不一致的情况。所以在多线程环境下,我们需要线程安全的队列;在Java中,提供了两种线程安全队列的实现方式:一种是阻塞机制,另一种是非阻塞机制。

使用阻塞机制的队列,是通过使用锁的方式来实现,在入队和出队时通过加锁避免并发操作,比如本文将要介绍的BlockingQueue就是一个线程安全的阻塞队列;而使用非阻塞机制的队列,是通过使用CAS方式实现,比如ConcurrentLinkedQueue。

那么本文将主要介绍阻塞队列——BlockingQueue。闲话少说,进入正题吧!

1. 什么是BlockingQueue?

BlockingQueue其实就是阻塞队列,是基于阻塞机制实现的线程安全的队列。而阻塞机制的实现是通过在入队和出队时加锁的方式避免并发操作。

BlockingQueue不同于普通的Queue的区别主要是:

通过在入队和出队时进行加锁,保证了队列线程安全 支持阻塞的入队和出队方法:当队列满时,会阻塞入队的线程,直到队列不满;当队列为空时,会阻塞出队的线程,直到队列中有元素。

BlockingQueue常用于生产者-消费者模型中,往队列里添加元素的是生产者,从队列中获取元素的是消费者;通常情况下生产者和消费者都是由多个线程组成;下图所示则为一个最常见的生产者-消费者模型,生产者和消费者之间通过队列平衡两者的的处理能力、进行解耦等。

2. BlockingQueue接口定义

BlockingQueue继承了Queue接口,在Queue接口基础上,又提供了若干其他方法,其定义源码如下:

public interface BlockingQueue extends Queue { /** * 入队一个元素,如果有空间则直接插入,并返回true; * 如果没有空间则抛出IllegalStateException */ boolean add(E e); /** * 入队一个元素,如果有空间则直接插入,并返回true; * 如果没有空间返回false */ boolean offer(E e); /** * 入队一个元素,如果有空间则直接插入,如果没有空间则一直阻塞等待 */ void put(E e) throws InterruptedException; /** * 入队一个元素,如果有空间则直接插入,并返回true; * 如果没有空间则等待timeout时间,插入失败则返回false */ boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException; /** * 出队一个元素,如果存在则直接出队,如果没有空间则一直阻塞等待 */ E take() throws InterruptedException; /** * 出队一个元素,如果存在则直接出队,如果没有空间则等待timeout时间,无元素则返回null */ E poll(long timeout, TimeUnit unit) throws InterruptedException; /** * 返回该队列剩余的容量(如果没有限制则返回Integer.MAX_VALUE) */ int remainingCapacity(); /** * 如果元素o在队列中存在,则从队列中删除 */ boolean remove(Object o); /** * 判断队列中是否存在元素o */ public boolean contains(Object o); /** * 将队列中的所有元素出队,并添加到给定的集合c中,返回出队的元素数量 */ int drainTo(Collection


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3