首页
学习
活动
专区
工具
TVP
发布

走进C#并发队列ConcurrentQueue的内部世界

前几天碰到一个小问题又读了一遍ConcurrentQueue的源码,那就拿C#中比较常用的并发队列ConcurrentQueue作为开篇来聊一聊它的实现原理。 话不多说,直奔主题。...事实上,在C#的普通队列Queue类型中选择使用数组进行实现,它实现了一套扩容机制,这里不再详细描述,有兴趣的直接看源码,比较简单。...而队列中维护了2个特殊的指针,他们分别指向队列的首段(head segment)和尾段(tail segment),他们对入队和出队有着重要的作用。用一张图来解释队列的内部结构: ?...到这里,一个并发队列就创建好了。 使用集合创建队列的过程和上面类似,只是多了两个步骤:入队和扩容,下面会重点描述这两部分所以这里不再过多介绍。...而在并发队列中就非常简单了,首先创建一个新Segment,然后把当前Segment的next指向它,最后挂到队列的末尾去就可以了,全部是指针操作非常高效。

1.9K20
您找到你想要的搜索结果了吗?
是的
没有找到

java并发队列之阻塞队列-ArrayBlockingQueue

正文 什么是阻塞队列 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。...阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。 阻塞队列有哪些?...extends E> c) 构造指定大小的有界队列,指定为公平或非公平锁,指定在初始化时加入一个集合 看一下ArrayBlockingQueue类中的几个成员变量: public class ArrayBlockingQueue...*/ int count; /* * 并发控制使用经典的两条件算法 *发现在任何教科书。...InterruptedException { abq.put(i); System.out.println("存入了一个元素是 " + i); } } 下面看输出,很明显多线程也没有发生并发问题

87720

并发容器和队列

2.9.3 Java中的队列 队列是一种数据结构,他有先进先出的性质,这点他和栈的性质正好相反。一般使用都是在队列尾部加入元素和从队列头部移除元素,我们经常把他使用在并发环境下。...LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列队列头部和尾部都可以添加和移除元素,多线程并发时,可以将锁的竞争最多降到一半。...extends E> c) 构造指定大小的有界队列,指定为公平或非公平锁,指定在初始化时加入一个集合 ArrayBlockingQueue类中的几个成员变量,如下代码清单2-41所示。...运行结果如下,可以看出多线程并发也没有发生线程安全问题,而且体现出队列是先入先出。...put/take方法可以实现在队列已满或空的时候达到线程阻塞状态,阻塞这种方式在线程并发时固然安全,但是也会造成效率上的问题,所以说今天我们来讲一个非阻塞队列——ConcurrentLinkedQueue

34120

并发队列 – 有界阻塞队列 ArrayBlockingQueue 原理探究

如图ArrayBlockingQueue内部有个数组items用来存放队列元素,putindex下标标示入队元素下标,takeIndex是出队下标,count统计队列元素个数,从定义可知道并没有使用volatile...另外构造函数必须传入队列大小参数,所以为有界队列,默认是Lock为非公平锁。...四、put操作 在队列尾部添加元素,如果队列满则等待队列有空位置插入后返回 publicvoidput(E e) throwsInterruptedException { checkNotNull...然后看了其他并发类里面凡是调用了await的方法获取锁时候都是使用的lockInterruptibly方法而不是Lock也验证了这个想法。...操作 从队头获取元素,如果队列为空则阻塞直到队列有元素。

55640

并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

转载自https://blog.csdn.net/westos_linux/article/details/78968012 在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列...Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非阻塞队列的典型例子是ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列...并行和并发区别 1、并行是指两者同时执行一件事,比如赛跑,两个人都在不停的往前跑; 2、并发是指资源有限的情况下,两者交替轮流使用资源,比如一段路(单核CPU资源)同时只能过一个人,A走一段后,让给B...,take方法在队列空的时候会阻塞,直到有队列成员被放进来。...take和put方法,这两个方法正是队列操作的阻塞版本。

81420

并发队列-无界阻塞队列LinkedBlockingQueue原理探究

return; c = ctl.get(); } //放入队列(2) if (isRunning(c) && workQueue.offer(command))...仔细思考下阻塞队列是如何实现并发安全的维护队列链表的,先分析下简单的情况就是当队列里面有多个元素时候,由于同时只有一个线程(通过独占锁putLock实现)入队元素并且是操作last节点(,而同时只有一个出队线程...(通过独占锁takeLock实现)操作head节点,所以不存在并发安全问题。...然后count.getAndIncrement()先获取当前队列元个数为0保存到c,然后自增count为1,由于c==0所以调用signalNotEmpty激活notEmpty的条件队列里面的阻塞时间最长的线程...put了,所以调用dequeue从队列获取元素(这时候一定可以获取到),然后调用c = count.getAndDecrement() 把当前计数返回后并减去1,如果c>1 说明当前队列还有其他元素,那么就调用

71930

并发阻塞队列BlockingQueue解读

并发阻塞队列BlockingQueue解读 引言 BlockingQueue 实现之 ArrayBlockingQueue 源码解读 构造函数 offer poll 循环队列 add remove put...其并发控制采用可重入锁来控制,不管是插入操作还是读取操作,都需要获取到锁才能进行操作。...这里说的并不是多线程的并发问题,而是因为当一个线程往队列中写入一个元素时,写入操作不会立即返回,需要等待另一个线程来将这个元素拿走;同理,当一个读线程做读操作的时候,同样需要一个相匹配的写线程的写操作。...---- BlockingQueue 实现之 PriorityBlockingQueue 带排序的 BlockingQueue 实现,其并发控制采用的是 ReentrantLock,队列为无界队列(ArrayBlockingQueue...super T>) c).compareTo((T) array[right]) > 0) c = array[child = right]; /

60320

解读 Java 并发队列 BlockingQueue

本文直接参考 Doug Lea 写的 Java doc 和注释,这也是我们在学习 java 并发包时最好的材料了。...其并发控制采用可重入锁来控制,不管是插入操作还是读取操作,都需要获取到锁才能进行操作。...(); } // 如果 c == capacity,那么说明在这个 take 方法发生的时候,队列是满的 // 既然出队了一个,那么意味着队列不满了,唤醒写线程去写 if...这里说的并不是多线程的并发问题,而是因为当一个线程往队列中写入一个元素时,写入操作不会立即返回,需要等待另一个线程来将这个元素拿走;同理,当一个读线程做读操作的时候,同样需要一个相匹配的写线程的写操作。...PriorityBlockingQueue 带排序的 BlockingQueue 实现,其并发控制采用的是 ReentrantLock,队列为无界队列(ArrayBlockingQueue 是有界队列

54541

解读 Java 并发队列 BlockingQueue

并发控制采用可重入锁来控制,不管是插入操作还是读取操作,都需要获取到锁才能进行操作。...首先,这里用一个示意图来看看 LinkedBlockingQueue 的并发读写控制,然后再开始分析源码: 看懂这个示意图,源码也就简单了,读操作是排好队的,写操作也是排好队的,唯一的并发问题在于一个写操作和一个读操作同时进行...(); } // 如果 c == capacity,那么说明在这个 take 方法发生的时候,队列是满的 // 既然出队了一个,那么意味着队列不满了,唤醒写线程去写 if...这里说的并不是多线程的并发问题,而是因为当一个线程往队列中写入一个元素时,写入操作不会立即返回,需要等待另一个线程来将这个元素拿走;同理,当一个读线程做读操作的时候,同样需要一个相匹配的写线程的写操作。...BlockingQueue 实现之 PriorityBlockingQueue 带排序的 BlockingQueue 实现,其并发控制采用的是 ReentrantLock,队列为无界队列(ArrayBlockingQueue

64010

Java并发编程:阻塞队列

Java并发编程:阻塞队列   在前面几篇文章中,我们讨论了同步容器(Hashtable、Vector),也讨论了并发容器(ConcurrentHashMap、CopyOnWriteArrayList)...二.阻塞队列中的方法 VS 非阻塞队列中的方法 1.非阻塞队列中的几个主要方法:   add(E e):将元素e插入到队列末尾,如果插入成功,则返回true;如果插入失败(即队列已满),则会抛出异常;...2.阻塞队列中的几个主要方法:   阻塞队列包括了非阻塞队列中的大部分方法,上面列举的5个方法在阻塞队列中都存在,但是要注意这5个方法在阻塞队列中都进行了同步措施。...extends E> c) { }    第一个构造器只有一个参数用来指定容量,第二个构造器可以指定容量和公平性,第三个构造器可以指定容量、公平性以及用另外一个集合进行初始化。   ...在并发编程中,一般推荐使用阻塞队列,这样实现可以尽量地避免程序出现意外的错误。

97640

Java并发队列与容器

【前言:无论是大数据从业人员还是Java从业人员,掌握Java高并发和多线程是必备技能之一。...本文主要阐述Java并发包下的阻塞队列并发容器,其实研读过大数据相关技术如Spark、Storm等源码的,会发现它们底层大多用到了Java并发队列、同步类容器、ReentrantLock等。...建议大家结合本篇文章,仔细分析一下相关源码】 BlockingQueue 阻塞队列,位于java.util.concurrent并发包下,它很好的解决了多线程中如何安全、高效的数据传输问题。...put方法在队列满的时候会阻塞直到有队列成员被消费,take方法在队列空的时候会阻塞,直到有队列成员被放进来。...因此不同的segment之间可以并发使用,极大地提高了性能。

44030

走进C#并发队列ConcurrentQueue的内部世界 — .NET Core篇

在上一篇《走进C#并发队列ConcurrentQueue的内部世界》中解析了Framework下的ConcurrentQueue实现原理,经过抛砖引玉,得到了一众大佬的指点,找到了.NET Core版本下的...创建实例 ConcurrentQueue依然提供了2个构造函数,分别可以创建一个空队列和指定数据集的队列。...object(); //计算得到第一段的长度 int length = InitialSegmentLength; if (collection is ICollection c)...{ int count = c.Count; if (count > length) { length = Math.Min...总结 对比Framework下的并发队列,Core里面的改动还是不小的,尽管保留了SpinWait和Interlocked相关操作,但是也加入了lock,逻辑上也复杂了很多,我一步步分析和写文章搞了好几天

1.3K40
领券