并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue在入队操作高并发性能比较

合集下载

ConcurrentLinkedQueue

ConcurrentLinkedQueue

ConcurrentLinkedQueueConcurrentLinkedQueue是⼀种⾮阻塞的线程安全队列,与阻塞队列LinkedBlockingQueue相对应,ConcurrentLinkedQueue同样也是使⽤链表实现的FIFO队列,但不同的是它没有使⽤任何锁机制,⽽是⽤CAS来实现线程安全。

1,成员变量1//头结点,transient表⽰该成员变量不会被序列化,volatile表⽰该变量的可见性和有序性2// head永远不会为null,它也不含数据域3//head.next是它本⾝,其他任何活动的节点通过succ⽅法,都能找到head节点4private transient volatile Node<E> head;5//可能的尾结点,该节点仅仅是⼀个优化,在O(1)的时间复杂度内查找尾结点6//最好还是使⽤head.next在O(n)的时间复杂度内找到节点7private transient volatile Node<E> tail; head和tail作为链表的⾸尾节点存在,说明ConcurrentLinkedQueue使⽤双向链表实现的,改双向链表存储着全部数据,但是head和tail 都被transient修饰,不会被序列化,由此可以推断, ConcurrentLinkedQueue应当实现了writeObject和readObject序列化⽅法来完成序列化。

1private void writeObject(java.io.ObjectOutputStream s) throws java.io.Exception {2 s.defaultWriteObject();3//从头遍历节点,写⼊流4for(Node<E> p = first(); p != null; p = succ(p)) {5 Object item = p.item;6if(item != null) {7 s.writeObject(item);8 }9//写⼊null作为结束符10 s.writeObject(null);11 }12}1314private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {15 s.defaultReadObject();16//读取元素直到读取到结束符null17 Node<E> h = null;18 Object item;19while((item = s.readObject()) != null) {20 @SuppressWarnings("unchecked")21 Node<E> newNode = new Node<E>((E)item);22if(h == null) {23 h = t = newNode;24 } else {25 zySetNext(newNode);26 t.newNode;27 }28 }29if(h == null) {30 h = t = new Node<E>(null);31 }32 head = h;33 tail = t;34 }2,UNSAFE和CAS在ConcurrentLinkedQueue⾥的应⽤ UNSAFE是java提供的⼀个不安全的操作类,他可以通过直接操作内存来灵活操作java对象,1static {2try {3//获取UNSAFE对象,只有jre的类才能使⽤此种⽅式获取4 UNSAFE = sun.misc.Unsafe.getUnsafe();5 Class<?> k = ConcurrentLinkedQueue.class;6//获取head字段在ConcurrentLinkedQueue勒种内存地址偏移量7 headOffset = UNSAFE.objectFieldOffset(k.getDeclaredField("head"));8//获取tail字段在ConcurrentLinkedQueue类中的内存地址偏移量9 tailOffset = UNSAFE.objectFieldOffset(k.getDeclaredField("tail"));10 } catch (Exception e) {11throw new Error();12 }13 }ConcurrentLinkedQueue的CAS操作针对的是head和tail,其节点实现类的CAS操作则针对的是next(下⼀个节点)和item(数据域)。

cuncurrentlinkedqueue 原理

cuncurrentlinkedqueue 原理

cuncurrentlinkedqueue 原理
ConcurrentLinkedQueue是一种无界线程安全的基于FIFO的非阻塞队列,基于wait-free实现。

它的原理如下:
- 结构组成:该队列由Node节点、head头节点、tail尾节点组成,其中Node节点是一个单链表结构,由item和next组成。

- 默认构造函数:head、tail节点默认指向一个item为null的Node节点。

- 入队过程:如果tail节点的next节点为空,则将入队节点设置为tail节点的next节点(此时不用更新tail节点);如果tail节点的next节点不为空,则将入队节点设置为tail节点,tail节点不总是尾节点。

ConcurrentLinkedQueue在写场景中采用乐观锁的思想,使用CAS+失败重试来保证操作的原子性。

为了避免CAS开销过大,它采用延迟更新首尾节点的思想,来减少CAS次数。

也就是说,ConcurrentLinkedQueue中的首尾节点并不一定是最新的首尾节点。

ConcurrentLinkedQueue在高并发环境中具有较好的性能,适合在对性能要求相对较高,同时对队列的读写存在多个线程同时进行的场景中使用。

java线程队列的用法

java线程队列的用法

java线程队列的用法
Java线程队列是一种用于管理和调度多线程任务的数据结构。

在Java中,线程队列通常使用ConcurrentLinkedQueue、LinkedBlockingQueue或PriorityBlockingQueue等类来实现。

这些队列提供了线程安全的操作,可以用于在多线程环境下进行任务调度和管理。

首先,让我们来看一下ConcurrentLinkedQueue。

这是一个基于链接节点的无界线程安全队列,它采用了无锁的线程安全算法,适用于高并发的场景。

它提供了常见的队列操作方法,如add、offer、poll、peek等,可以用于在线程池中管理任务。

另外一个常用的线程队列是LinkedBlockingQueue,它是一个基于链表的有界队列。

它可以指定队列的容量,当队列满时会阻塞生产者线程,直到队列有空间为止。

这种队列适合于限制任务数量的场景,比如控制线程池的最大任务数。

除了上述两种队列外,还有PriorityBlockingQueue,它是一个支持优先级的无界阻塞队列。

在这种队列中,元素按照它们的自然顺序或者根据构造队列时提供的Comparator进行排序。

这种队列
适合于需要按照优先级处理任务的场景。

在实际应用中,我们可以利用这些线程队列来实现生产者-消费者模式、任务调度和消息传递等功能。

通过合理选择队列类型和合理设置队列容量,可以提高多线程程序的效率和性能。

总的来说,Java线程队列是多线程编程中非常重要的一部分,它提供了一种安全、高效的方式来管理和调度多线程任务。

合理地使用线程队列可以帮助我们编写出稳定、高性能的多线程程序。

concurrentlinkedqueue 容量

concurrentlinkedqueue 容量

concurrentlinkedqueue 容量并解释并发链表队列(ConcurrentLinkedQueue)的容量问题。

第一部分:介绍并发链表队列(ConcurrentLinkedQueue)并发链表队列是一种线程安全的队列数据结构,它广泛用于多线程应用程序中。

该队列采用链表的形式,支持高效地完成插入和删除操作,而不需要任何同步措施。

在多线程环境下,各个线程可以同时操作队列,而不会导致数据的错误或不一致。

这是因为并发链表队列使用了一系列的算法和数据结构,以确保线程安全性和高效性。

第二部分:并发链表队列的无界特性与许多其他队列实现不同,ConcurrentLinkedQueue是一种无界队列,它没有预先定义的容量限制。

这意味着队列可以根据需要自动调整大小,并支持无限数量的元素。

在任何时候,我们都可以将元素添加到队列中,而不需要担心容量是否已满或是否需要重新调整大小。

第三部分:为什么并发链表队列没有容量限制并发链表队列没有特定的容量限制,是由于其底层数据结构和算法的设计。

链表是一种动态数据结构,它可以根据需要随时增加或减少节点。

因此,并发链表队列可以根据元素的增加或删除调整其大小。

另外,并发链表队列是基于一种CAS(Compare And Swap)算法实现的。

CAS算法可以保证并发操作的线程安全性。

在插入或删除元素时,只有当队列的状态与操作之间的预期状态相符时,才能成功执行操作。

如果并发操作之间存在竞争,那么只有一个线程能够成功执行操作,而其他线程将重试。

第四部分:并发链表队列的性能考虑尽管并发链表队列没有容量限制,但是在实际应用中,我们仍然需要考虑性能问题。

首先,由于并发链表队列是无界的,所以在某些极端情况下,队列可能会无限增长,占用大量内存。

为了避免这种情况,我们可以使用其他方法来限制队列的大小,比如设置一个阈值,当达到该阈值时,停止向队列中添加元素。

其次,并发链表队列的性能取决于并发访问的数量和类型。

concurrentqueue linkedblockingqueue原理(一)

concurrentqueue linkedblockingqueue原理(一)

concurrentqueue linkedblockingqueue原理(一)concurrentqueue和LinkedBlockingQueue原理什么是concurrentqueue?concurrentqueue是一个多线程环境下线程安全的队列实现,它允许多个线程同时读写队列中的元素。

它主要用于解决多线程环境下的队列操作问题。

什么是LinkedBlockingQueue?LinkedBlockingQueue是Java中的一个阻塞队列实现,它基于链表结构,它允许多个线程同时读写队列中的元素,并且支持阻塞操作。

它主要用于解决多线程环境下的生产者-消费者问题。

concurrentqueue原理详解concurrentqueue的实现主要依赖于两个关键技术:CAS (Compare-and-Swap)和volatile。

CAS是一种无锁的同步机制,它通过比较内存中的值和期望值来确定是否进行更新。

当多个线程同时对一个变量进行更新时,只有一个线程能够成功更新,其他线程需要重试。

volatile是一种轻量级的同步机制,它保证了可见性和有序性。

当一个变量被声明为volatile,任何对该变量的修改都会立即刷新到主内存,并且任何对该变量的读取都会从主内存中获取最新的值。

concurrentqueue内部使用了一个环形数组作为底层数据结构,该数组中的每个元素都包含一个元素值和一个状态。

其中,状态用于标记元素是否可访问。

当一个线程要向队列中添加元素时,它首先通过CAS操作获取到队列的尾部指针,并将元素添加到尾部指针所指向的位置。

然后,它通过CAS操作将尾部指针向后移动一位。

当一个线程要从队列中弹出元素时,它首先通过CAS操作获取到队列的头部指针,并获取头部指针所指向的元素值。

然后,它通过CAS 操作将头部指针向后移动一位。

这样,多个线程可以同时对队列进行读写操作,而不会出现线程安全问题。

LinkedBlockingQueue原理详解LinkedBlockingQueue的实现也是基于链表结构,它使用了一个链表来存储队列中的元素。

java中的各种Queue

java中的各种Queue

java中的各种Queue java中的各种并发Queue可以归为以下的⼏种: ConcurrentLinkedQueue:⼀个由链表结构组成的⾮阻塞队列ArrayBlockingQueue :⼀个由数组结构组成的有界阻塞队列LinkedBlockingQueue :⼀个由链表结构组成的有界阻塞队列PriorityBlockingQueue :⼀个⽀持优先级排序的⽆界阻塞队列DelayQueue:⼀个使⽤优先级队列实现的⽆界阻塞队列SynchronousQueue:⼀个不存储元素的阻塞队列LinkedTransferQueue:⼀个由链表结构组成的⽆界阻塞队列LinkedBlockingDeque:⼀个由链表结构组成的双向阻塞队列 ConcurrentLinkedQueue ConcurrentLinkedQueue不能阻塞队列,但是速度快。

在不需要阻塞的情况下,应该优选ConcurrentLinkedQueue。

ArrayBlockingQueue ArrayBlockingQueue是⼀个⽤数组实现的有界阻塞队列。

在队列⼤⼩固定的情况下是优先选择,⼊队出队只有⼀把锁,锁的竞争会⽐较激烈。

LinkedBlockingQueue LinkedBlockingQueue是⼀个⽤链表实现的有界阻塞队列,此队列的默认和最⼤长度为Integer.MAX_VALUE。

在队列⼤⼩没有限制的情况下优先选择。

⼊队和出队做了锁分离,对于锁的竞争会⽐较⼩。

由于LinkedBlockingQueue是基于链表实现的,当队列容量较⼤,做查找操作时会⽐较耗时。

PriorityBlockingQueue PriorityBlockingQueue是⼀个⽀持优先级的⽆界队列。

默认情况下元素采取⾃然顺序排列,也可以通过⽐较器comparator来指定元素的排序规则。

需要对队列中的元素做排序操作时,PriorityBlockingQueue是唯⼀的选择。

concurrentlinkeddeque 的使用方式-概述说明以及解释

concurrentlinkeddeque 的使用方式-概述说明以及解释

concurrentlinkeddeque 的使用方式-概述说明以及解释1.引言1.1 概述ConcurrentLinkedDeque是Java并发包(java.util.concurrent)中提供的一种线程安全的无界双向链表。

它是对Deque接口的一个实现,具有高效且线程安全的特性。

在多线程环境下,使用ConcurrentLinkedDeque可以实现并发地访问和修改数据,而无需显式地加锁。

这种高并发的特性使得ConcurrentLinkedDeque在并发编程中非常有用,尤其是在生产者-消费者模式或者任务调度等场景中。

与传统的LinkedList不同,ConcurrentLinkedDeque在插入和删除元素时,无需复制整个链表,而是采用一种无锁算法,利用CAS操作来实现线程安全。

这使得ConcurrentLinkedDeque的性能较好,能够保持较高的吞吐量。

ConcurrentLinkedDeque的结构是由一系列节点构成的双向链表,每个节点都包含了前一个节点和后一个节点的引用。

在并发情况下,节点的插入和删除操作只会影响到相邻节点,不会产生线程间的竞争。

在使用ConcurrentLinkedDeque时,需要注意的是,它不是一个有序的集合,因为无法保证元素的插入顺序与元素的遍历顺序完全一致。

如果需要有序的访问,可以考虑使用其他的线程安全有序集合,如ConcurrentSkipListSet等。

在接下来的正文部分,我们将详细介绍ConcurrentLinkedDeque的基本使用方式,包括如何插入、删除和遍历元素,以及如何处理并发访问时可能出现的一些情况。

同时,我们也会提供一些使用ConcurrentLinkedDeque的建议,帮助读者更好地利用这个高效的并发容器。

1.2 文章结构文章结构部分的内容可以包括以下内容:文章的结构是指文章的整体布局和组织方式,包括各个章节的标题和内容顺序。

concurrentlinkedqueue 容量

concurrentlinkedqueue 容量

concurrentlinkedqueue 容量ConcurrentLinkedQueue 是 Java.util.concurrent 包中的一个并发集合类,它实现了 Queue 接口,是一个先进先出(FIFO)的队列。

与其他并发队列不同的是,ConcurrentLinkedQueue 不是有界的,也就是说它没有固定的容量限制。

本文将重点讨论 ConcurrentLinkedQueue 的容量和其特点。

ConcurrentLinkedQueue 是基于链表实现的队列,它采用无锁算法(Lock-Free)来实现线程安全。

这意味着多个线程可以同时进行插入(offer)和删除(poll)操作,而不需要互斥锁,从而提高了并发性能。

ConcurrentLinkedQueue 使用 CAS (Compare and Swap)操作来保证数据的一致性。

由于底层是链表结构,ConcurrentLinkedQueue 不需要预先指定容量大小,因此理论上它的容量可以是无限的。

当队列中的元素超过 JVM 虚拟机内存限制时,ConcurrentLinkedQueue 会自动进行内存扩容,以适应更多的元素。

需要注意的是,虽然 ConcurrentLinkedQueue 没有明确的容量限制,但是在实践中,由于内存资源的有限性,实际的容量仍然是有限的。

当插入元素超过 JVM堆内存限制时,可能会导致 OutOfMemoryError 异常。

另外,在使用 ConcurrentLinkedQueue 时要注意,它是一个无界队列,即使队列为空,调用 poll 方法也不会返回 null 值,而是会立即返回一个空值。

因此,在使用 poll 方法时应该对返回值进行判空处理,以避免出现空指针异常。

在实际应用中,ConcurrentLinkedQueue 通常被用于多线程或并发环境下的任务调度、消息传递等场景。

由于它的高并发性和无锁算法的特点,ConcurrentLinkedQueue 在读多写少的场景下表现出色。

ConcurrentLinkedQueue详解

ConcurrentLinkedQueue详解

ConcurrentLinkedQueue详解ConcurrentLinkedQueue详解简介实现线程安全的队列的两种⽅式:使⽤阻塞算法:对⼊队和出队使⽤同⼀把锁(或不同的锁).使⽤⾮阻塞算法:使⽤循环CAS⽅式实现.ConcurrentLinkedQueue是⼀个基于链接节点的⽆界线程安全队列.采⽤先进先出规则对节点排序.添加元素会添加到队列的尾部,获取元素会返回队列头部元素.结构有两个结点:头节点(head)和尾节点(tail).每个节点由结点元素(item)和指向下⼀个节点的指针(next)组成.默认情况下head节点存储的元素为空,tail节点等于head节点.操作⼊队列将⼊队节点添加到队列尾部.public boolean offer(E e) {checkNotNull(e);final Node<E> newNode = new Node<E>(e);for (Node<E> t = tail, p = t;;) {Node<E> q = p.next;if (q == null) {if (p.casNext(null, newNode)) {if (p != t)casTail(t, newNode);return true;}}else if (p == q)p = (t != (t = tail)) ? t : head;elsep = (p != t && t != (t = tail)) ? t : q;}}流程:定位尾节点.使⽤CAS将⼊队节点设置为尾节点的next节点,若不成功,则重试.定位尾节点:tail节点并⾮总是尾节点.每次⼊队必须先通过tail节点查找尾节点.设置⼊队节点为尾节点:设置⼊队节点为当前尾节点的next节点.刚开始head和tail节点都指向空节点.添加⼀个节点后,head和tail仍然指向空节点.再添加节点时,head指向空节点,tail指向尾节点.再次添加节点时,tail保持不变.再添加结点时,tail指向尾节点.出队列出队列是从队列中返回⼀个节点元素.public E poll() {restartFromHead:for (;;) {for (Node<E> h = head, p = h, q;;) {E item = p.item;if (item != null && p.casItem(item, null)) {if (p != h)updateHead(h, ((q = p.next) != null) ? q : p);return item;}else if ((q = p.next) == null) {updateHead(h, p);return null;}else if (p == q)continue restartFromHead;elsep = q;}}}流程:当head节点有元素时,直接弹出head节点对应的元素,不更新head节点.当head节点没有元素时,出队操作更新head节点.⽬的:减少使⽤CAS更新head节点的消耗,提⾼效率.先获取头节点的元素.再判断头节点元素是否为空.如果为空,则另外⼀个线程已进⾏出队操作.若不为空,则使⽤CAS⽅式将头节点的引⽤设为null.成功则直接返回头节点元素;不成功则其他线程已进⾏出队操作更新head节点,需重新获取头节点.参考:。

concurrentlinkedqueue 默认长度

concurrentlinkedqueue 默认长度

concurrentlinkedqueue 默认长度摘要:1.concurrentLinkedQueue 的概念2.concurrentLinkedQueue 的默认长度3.concurrentLinkedQueue 的主要特点4.concurrentLinkedQueue 的应用场景5.如何根据需求调整concurrentLinkedQueue 的长度正文:concurrentLinkedQueue 是Java 并发编程中的一个重要数据结构,它是一个无界非阻塞的队列,可以用于多线程之间的通信和数据同步。

concurrentLinkedQueue 的默认长度为11,这是一个在创建时被初始化的值。

concurrentLinkedQueue 的主要特点包括:- 无界:队列可以无限存储元素,不会溢出。

- 非阻塞:插入和删除操作都是非阻塞的,即不需要等待队列满或者为空。

- 公平:所有线程在队列中的操作都是公平的,即按照先进先出的原则。

concurrentLinkedQueue 可以广泛应用于多线程并发编程中,例如:- 任务分发:将任务添加到队列中,由多个线程并行执行。

- 生产者消费者模型:生产者将数据添加到队列中,消费者从队列中取出数据进行处理。

- 异步消息处理:例如网络通信中的数据接收和处理。

当我们需要根据实际需求调整concurrentLinkedQueue 的长度时,可以通过以下方式实现:- 创建一个新的concurrentLinkedQueue,指定新的初始长度。

- 如果需要调整现有队列的长度,可以通过调用`transfer()` 方法将队列中的元素转移到新的队列中,然后重新创建一个新的concurrentLinkedQueue,并将原有队列的元素转移过去。

总之,concurrentLinkedQueue 是一个非常有用的Java 并发编程数据结构,它具有无界、非阻塞和公平等特点,适用于多种应用场景。

concurrentlinkedqueue类使用线程方式自动出队的例子

concurrentlinkedqueue类使用线程方式自动出队的例子

concurrentlinkedqueue类使用线程方式自动出队的例子ConcurrentLinkedQueue是一个Java并发包中的线程安全队列,它使用非阻塞的并发算法实现,具有高效的性能和低延迟的访问。

ConcurrentLinkedQueue类提供了一种线程安全的方式来管理队列中的元素,允许多个线程同时访问和修改队列,而不会出现数据不一致的情况。

在使用ConcurrentLinkedQueue类时,我们通常会使用Java多线程编程技术来提高程序的效率和性能。

通过使用多个线程来自动出队元素,可以减少阻塞和等待时间,提高程序的响应速度和吞吐量。

下面是一个使用ConcurrentLinkedQueue类实现自动出队元素的示例代码:```javaimport java.util.concurrent.ConcurrentLinkedQueue;public class ConcurrentQueueExample {private ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<>();public void addElement(int element) {queue.add(element);}public void removeElement() throws InterruptedException {queue.poll(); // 自动出队元素}public static void main(String[] args) {ConcurrentQueueExample example = new ConcurrentQueueExample();// 创建两个线程来自动出队元素Thread t1 = new Thread(() -> {try {example.removeElement();} catch (InterruptedException e) {e.printStackTrace();}});Thread t2 = new Thread(() -> {while (true) {int element = example.queue.poll(); // 自动出队元素if (element != null) {System.out.println("Removed element: " + element);} else {try {Thread.sleep(100); // 等待元素被添加到队列中} catch (InterruptedException e) {e.printStackTrace();}}}});// 启动线程t1和t2t1.start();t2.start();}}```在上面的示例代码中,我们首先创建了一个ConcurrentLinkedQueue对象,用于存储队列中的元素。

concurrentlinkedqueue使用场景

concurrentlinkedqueue使用场景

concurrentlinkedqueue使用场景摘要:1.concurrentLinkedQueue 简介2.concurrentLinkedQueue 的特点3.concurrentLinkedQueue 的使用场景4.总结正文:1.concurrentLinkedQueue 简介concurrentLinkedQueue 是一个由Java 语言提供的高效、线程安全的无界非阻塞队列。

它基于链表实现,能够支持多线程并发操作,主要用于替代传统的ArrayList 和LinkedList。

由于它采用无锁设计,因此在多线程并发访问时,不需要进行同步控制,从而减少了性能开销。

2.concurrentLinkedQueue 的特点concurrentLinkedQueue 具有以下特点:(1)线程安全:无需进行同步控制,降低了性能开销。

(2)高效:基于链表实现,插入和删除操作的时间复杂度为O(1)。

(3)无界:队列大小没有上限,可以无限存储元素。

(4)非阻塞:无需等待,可以随时进行插入和删除操作。

3.concurrentLinkedQueue 的使用场景concurrentLinkedQueue 主要适用于以下场景:(1)多线程并发操作:当需要处理大量并发任务时,concurrentLinkedQueue 可以有效提高程序性能,因为它不需要进行同步控制。

(2)数据处理:在数据处理任务中,concurrentLinkedQueue 可以作为数据缓冲区,用于临时存储处理过程中的数据,提高数据处理效率。

(3)异步任务队列:concurrentLinkedQueue 可以作为异步任务队列,用于存储待执行的任务,支持多线程并发执行任务。

(4)事件驱动系统:在事件驱动系统中,concurrentLinkedQueue 可以作为事件队列,用于存储待处理的事件,提高系统响应速度。

4.总结concurrentLinkedQueue 是一个高效、线程安全的无界非阻塞队列,适用于多线程并发操作、数据处理、异步任务队列和事件驱动系统等场景。

ConcurrentLinkedQueue简介

ConcurrentLinkedQueue简介

下面从 ConcurrentLinkedQueue 的创建,添加,删除这几个方面对它进行分析。 1 创建 下面以 ConcurrentLinkedQueue()来进行说明。 public ConcurrentLinkedQueue() { head = tail = new Node<E>(null); } 说明:在构造函数中,新建了一个“内容为 null 的节点”,并设置表头 head 和表尾 tail 的值为新节点。 head 和 tail 的定义如下: private transient volatile Node<E> head; private transient volatile Node<E> tail; 2/9
public E poll() { // 设置“标记” restartFromHead: for (;;) { for (Node<E> h = head, p = h, q;;) { E item = p.item; // 情况 1 // 表头的数据不为 null,并且“设置表头的数据为 null”这个操作成功的话; // 则比较“p 和 h”(若 p!=h,即表头发生了变化,则更新表头,即设置表头为 p),然后返回原表头的 item 值。 if (item != null && p.casItem(item, null)) { if (p != h) // hop two nodes at a time updateHead(h, ((q = p.next) != null) ? q : p); return item; } // 情况 2 // 表头的下一个节点为 null,即链表只有一个“内容为 null 的表头节点”。则更新表头为 p,并返回 null。 else if ((q = p.next) == null) { updateHead(h, p); return null; } // 情况 3 // 这可能到由于“情况 4”的发生导致 p=q,在该情况下跳转到 restartFromHead 标记重新操作。 else if (p == q) continue restartFromHead; // 情况 4 // 设置 p 为 q else p = q; }

concurrentlinkedqueue使用场景

concurrentlinkedqueue使用场景

concurrentlinkedqueue使用场景ConcurrentLinkedQueue是一种基于链表的线程安全队列,它提供了高效的并发操作,适用于许多场景。

在这篇文章中,我们将探讨ConcurrentLinkedQueue的使用场景,并提供一些实践建议。

一、概述ConcurrentLinkedQueueConcurrentLinkedQueue是Java并发包(java.util.concurrent)中的一员,它是一个无界队列,支持高效的并发插入和移除操作。

与传统的ArrayList 和LinkedList相比,ConcurrentLinkedQueue在并发操作上具有更好的性能,因为它使用了CAS(Compare and Swap)算法来实现线程安全。

二、ConcurrentLinkedQueue的使用场景1.生产者消费者场景:在多线程环境下,ConcurrentLinkedQueue可以用于实现生产者和消费者之间的解耦。

生产者线程可以向队列中插入元素,消费者线程则从队列中取出元素进行处理。

通过使用ConcurrentLinkedQueue,可以确保生产者和消费者线程之间的数据同步,避免竞争条件和死锁。

2.异步处理:ConcurrentLinkedQueue可以用于实现异步处理机制。

例如,在一个服务器程序中,当接收到客户端请求时,可以将请求封装成对象放入ConcurrentLinkedQueue中。

然后,专门的工作线程从队列中取出请求并进行处理。

这样可以有效地实现请求处理和线程之间的解耦,提高程序的并发性能。

3.任务分发:在分布式系统中,可以使用ConcurrentLinkedQueue来实现任务分发。

将任务封装成对象放入队列中,然后由工作者线程池取出任务并进行处理。

这样可以确保任务在分布式节点之间的同步,并提高系统的吞吐量。

4.事件驱动架构:ConcurrentLinkedQueue可以用于实现事件驱动的应用架构。

concurrentlinkedqueue使用场景

concurrentlinkedqueue使用场景

concurrentlinkedqueue使用场景【实用版】目录1.ConcurrentLinkedQueue 的定义和特点2.ConcurrentLinkedQueue 的使用场景3.ConcurrentLinkedQueue 的优缺点4.实际应用案例正文一、ConcurrentLinkedQueue 的定义和特点ConcurrentLinkedQueue(并发链表队列)是 Java 并发编程中常用的一种数据结构,它是基于链表结构的并发队列。

ConcurrentLinkedQueue 允许多个生产者和消费者并发地向队列中添加和移除元素,因此具有很高的并发性能。

二、ConcurrentLinkedQueue 的使用场景1.需要高效并发添加和移除元素的场景:由于ConcurrentLinkedQueue 基于链表结构,其添加和移除元素的操作具有较低的时间复杂度,因此非常适合需要高效并发操作的场景。

2.需要动态调整队列大小的场景:ConcurrentLinkedQueue 可以根据需要动态调整队列大小,这使得它在处理不确定大小的任务队列时具有很好的适应性。

3.需要高并发性能的场景:ConcurrentLinkedQueue 允许多个生产者和消费者并发地向队列中添加和移除元素,因此具有很高的并发性能,适合高并发的场景。

三、ConcurrentLinkedQueue 的优缺点优点:1.基于链表结构,支持动态调整队列大小。

2.允许多个生产者和消费者并发地向队列中添加和移除元素,具有高并发性能。

3.添加和移除元素的操作具有较低的时间复杂度。

缺点:1.相对于其他阻塞队列,ConcurrentLinkedQueue 的性能优势在等待时间较长时才能体现出来。

2.内存开销较大,因为需要维护链表结构。

四、实际应用案例1.消息队列:在高并发的系统中,ConcurrentLinkedQueue 可以用作消息队列,用于存储生产者发送的消息,消费者可以从队列中获取并处理消息。

java中并发Queue种类与各自API特点以及使用场景!

java中并发Queue种类与各自API特点以及使用场景!

java中并发Queue种类与各⾃API特点以及使⽤场景!⼀先说下队列队列是⼀种数据结构.它有两个基本操作:在队列尾部加⼊⼀个元素,和从队列头部移除⼀个元素(注意不要弄混队列的头部和尾部)就是说,队列以⼀种先进先出的⽅式管理数据,如果你试图向⼀个已经满了的阻塞队列中添加⼀个元素或者是从⼀个空的阻塞队列中移除⼀个元索,将导致线程阻塞.在多线程进⾏合作时,阻塞队列是很有⽤的⼯具。

⼯作者线程可以定期地把中间结果存到阻塞队列中⽽其他⼯作者线程把中间结果取出并在将来修改它们。

队列会⾃动平衡负载。

如果第⼀个线程集运⾏得⽐第⼆个慢,则第⼆个线程集在等待结果时就会阻塞。

如果第⼀个线程集运⾏得快,那么它将等待第⼆个线程集赶上来.说⽩了,就是先进先出,线程安全!java中并发队列都是在java.util.concurrent并发包下的,Queue接⼝与List、Set同⼀级别,都是继承了Collection接⼝,最近学习了java中的并发Queue 的所有⼦类应⽤场景,这⾥记录分享⼀下:1.1 这⾥可以先⽤wait与notify(脑忒fai) 模拟⼀下队列的增删数据,简单了解⼀下队列:import java.util.LinkedList;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicInteger;/*** 模拟队列增删数据* @author houzheng*/public class MyQueue {//元素集合private LinkedList<Object> list=new LinkedList<Object>();//计数器(同步),判断集合元素数量private AtomicInteger count=new AtomicInteger();//集合上限与下限,final必须指定初值private final int minSize=0;private final int maxSize;//构造器指定最⼤值public MyQueue(int maxSize) {this.maxSize = maxSize;}//初始化对象,⽤于加锁,也可直接⽤thisprivate Object lock=new Object();//put⽅法:往集合中添加元素,如果集合元素已满,则此线程阻塞,直到有空间再继续public void put(Object obj){synchronized (lock) {while(count.get()==this.maxSize){try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}list.add(obj);//计数器加⼀count.incrementAndGet();System.out.println("放⼊元素:"+obj);//唤醒另⼀个线程,(处理极端情况:集合⼀开始就是空,此时take线程会⼀直等待)lock.notify();}}//take⽅法:从元素中取数据,如果集合为空,则线程阻塞,直到集合不为空再继续public Object take(){Object result=null;synchronized(lock){while(count.get()==this.minSize){try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}//移除第⼀个result=list.removeFirst();//计数器减⼀count.decrementAndGet();System.out.println("拿⾛元素:"+result);//唤醒另⼀个线程,(处理极端情况:集合⼀开始就是满的,此时put线程会⼀直等待)lock.notify();}return result;}public int getSize(){return this.count.get();}public static void main(String[] args) {//创建集合容器MyQueue queue=new MyQueue(5);queue.put("1");queue.put("2");queue.put("3");queue.put("4");queue.put("5");System.out.println("当前容器长度为:"+queue.getSize());Thread t1=new Thread(()->{queue.put("6");queue.put("7");},"t1");Thread t2=new Thread(()->{Object take1 = queue.take();Object take2 = queue.take();},"t2");//测试极端情况,两秒钟后再执⾏另⼀个线程t1.start();try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}t2.start();}} 这⾥⽤线程通信的⽅式简单模拟了队列的进出,那么接下来就正式进⼊java的并发队列:⼆并发QueueJDK中并发队列提供了两种实现,⼀种是⾼性能队列ConcurrentLinkedQueue,⼀种是阻塞队列BlockingQueue,两种都继承⾃Queue:1 ConcurrentLinkedQueue这是⼀个使⽤于⾼并发场景的队列(额,各位看这块博客的⼩朋友,最好对线程基础⽐较熟悉再来看,当然我也在拼命店铺,哈哈哈),主要是⽆锁的⽅式,他的想能要⽐BlockingQueue好,是基于链接节点的⽆界线程安全队列,先进先出,不允许有null元素,废话不多说,上demo:这种queue⽐较简单,没什么好说的,和ArrayList⼀样⽤就可以,关键是BlockingQUeue2 BlockingQueueblockingQueue主要有5中实现,我感觉都挺有意思的,其中⼏种还⽐较常⽤就都学习了下,这⾥都介绍下:2.1 ArrayBlockingQueue@Testpublic void test02() throws Exception{//必须指定队列长度ArrayBlockingQueue<String> abq=new ArrayBlockingQueue<String>(2);abq.add("a");//add :添加元素,如果BlockingQueue可以容纳,则返回true,否则抛异常,⽀持添加集合System.out.println(abq.offer("b"));//容量如果不够,返回false//offer: 如果可能的话,添加元素,即如果BlockingQueue可以容纳,则返回true,否则返回false,⽀持设置超时时间//设置超时,如果超过时间就不添加,返回false,abq.offer("d", 2, TimeUnit.SECONDS);// 添加的元素,时长,单位//put 添加元素,如果BlockQueue没有空间,则调⽤此⽅法的线程被阻断直到BlockingQueue⾥⾯有空间再继续.abq.put("d");//会⼀直等待//poll 取⾛头部元素,若不能⽴即取出,则可以等time参数规定的时间,取不到时返回null,⽀持设置超时时间abq.poll();abq.poll(2,TimeUnit.SECONDS);//两秒取不到返回null//take() 取⾛头部元素,若BlockingQueue为空,阻断进⼊等待状态直到Blocking有新的对象被加⼊为⽌abq.take();//取出头部元素,但不删除abq.element();//drainTo()//⼀次性从BlockingQueue获取所有可⽤的数据对象(还可以指定获取数据的个数),通过该⽅法,可以提升获取数据效率;不需要多次分批加锁或释放锁。

并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue在入队操作高并发性能比较

并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue在入队操作高并发性能比较

并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue在入队操作高并发性能比较并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue在入队操作高并发性能比较2011-01-19 08:522802人阅读测试结果显示:阻塞队列和并发队列在高并发情况下,性能相差不大。

1 Test.java代码参考/arkblue/archive/2011/01/14/6138598.aspx[ja va] view plaincopyprint?public class ConcurrentQueueTest {private static int COUNT = 100000;private static int THREAD_NUM = 10;private static CyclicBarrierThread cyclicBarrierThread = new CyclicBarrierThread();private static ConcurrentLinkedQueue conQueue = newConcurrentLinkedQueue();private static LinkedBlockingQueue linkQueue = new LinkedBlockingQueue();static class ConcurrentLinkedQueueProducer extends Test {public ConcurrentLinkedQueueProducer(String id, CyclicBarrier barrier,long count, int threadNum, ExecutorService executor) { super(id, barrier, count, threadNum, executor);}@Overrideprotected void test() {conQueue.add(1);}}static class LinkedBlockingQueueProducer extends Test {public LinkedBlockingQueueProducer(String id, CyclicBarrier barrier,long count, int threadNum, ExecutorService executor) { super(id, barrier, count, threadNum, executor);}@Overrideprotected void test() {conQueue.add(1);}}static class CyclicBarrierThread extends Thread {@Overridepublic void run() {conQueue.clear();linkQueue.clear();}}public static void test(String id, long count, int threadNum, ExecutorService executor) {final CyclicBarrier barrier = new CyclicBarrier(threadNum + 1,cyclicBarrierThread);System.out.println("==============================") ;System.out.println("count = " + count + "/t" + "Thread Count = "+ threadNum);concurrentTotalTime += new ConcurrentLinkedQueueProducer( "ConcurrentLinkedQueueProducer", barrier, COUNT, threadNum,executor).startTest();linkedBlockingTotalTime += new LinkedBlockingQueueProducer( "LinkedBlockingQueueProducer ", barrier, COUNT, threadNum,executor).startTest();totalThreadCount += threadNum;executor.shutdownNow();System.out.println("==============================")}static long concurrentTotalTime = 0;static long linkedBlockingTotalTime = 0;static long totalThreadCount = 0;public static void main(String[] args) throws InterruptedException {for (int i = 1; i 20; i++) {ExecutorService executor =Executors.newFixedThreadPool(THREAD_NUM* i);test("", COUNT, 10 * i, executor);}System.out.println("ConcurrentLinkedQueue Avg Time = " + concurrentTotalTime / totalThreadCount);System.out.println("LinkedBlockingQueue Avg Time = " + linkedBlockingTotalTime / totalThreadCount);} public class ConcurrentQueueTest {private static int COUNT = 100000;private static int THREAD_NUM = 10;private static CyclicBarrierThread cyclicBarrierThread = new CyclicBarrierThread(); private static ConcurrentLinkedQueue conQueue = new ConcurrentLinkedQueue();private static LinkedBlockingQueue linkQueue = new LinkedBlockingQueue(); static class ConcurrentLinkedQueueProducer extends Test { public ConcurrentLinkedQueueProducer(String id, CyclicBarrier barrier,long count, int threadNum, ExecutorService executor) {super(id, barrier, count, threadNum, executor);} @Overrideprotected void test() {conQueue.add(1);}} static class LinkedBlockingQueueProducer extends Test { public LinkedBlockingQueueProducer(String id,CyclicBarrier barrier,long count, int threadNum, ExecutorService executor) {super(id, barrier, count, threadNum, executor);} @Overrideprotected void test() {conQueue.add(1);}} static class CyclicBarrierThread extends Thread { @Overridepublic void run() {conQueue.clear();linkQueue.clear();}} public static void test(String id, long count, int threadNum,ExecutorService executor) { final CyclicBarrier barrier = new CyclicBarrier(threadNum + 1,cyclicBarrierThread);System.out.println("============================= =");System.out.println("count = " + count + "/t" + "ThreadCount = "+ threadNum); concurrentTotalTime += new ConcurrentLinkedQueueProducer("ConcurrentLinkedQueueProducer", barrier, COUNT, threadNum,executor).startTest();linkedBlockingTotalTime += new LinkedBlockingQueueProducer("LinkedBlockingQueueProducer ", barrier, COUNT, threadNum,executor).startTest(); totalThreadCount += threadNum;executor.shutdownNow();System.out.println("============================= =");} static long concurrentTotalTime = 0;static long linkedBlockingTotalTime = 0; static long totalThreadCount = 0; public static void main(String[] args) throws InterruptedException {for (int i = 1; i < 20; i++) {ExecutorService executor =Executors.newFixedThreadPool(THREAD_NUM* i);test("", COUNT, 10 * i, executor);} System.out.println("ConcurrentLinkedQueue Avg Time = "+ concurrentTotalTime / totalThreadCount);System.out.println("LinkedBlockingQueue Avg Time = "+ linkedBlockingTotalTime / totalThreadCount);}}结果,执行100,000次的并发入队操作,并发队列需要49毫秒,阻塞队列需要53毫秒,比阻塞队列平均快4毫秒。

ConcurrentLinkedQueue使用和方法介绍

ConcurrentLinkedQueue使用和方法介绍

ConcurrentLinkedQueue使⽤和⽅法介绍定义⼀个基于链接节点的⽆界线程安全队列。

此队列按照 FIFO(先进先出)原则对元素进⾏排序。

队列的头部是队列中时间最长的元素。

队列的尾部是队列中时间最短的元素。

新的元素插⼊到队列的尾部,队列获取操作从队列头部获得元素。

当多个线程共享访问⼀个公共 collection 时,ConcurrentLinkedQueue 是⼀个恰当的选择。

此队列不允许使⽤null元素。

offer和poll( e)将指定元素插⼊此队列的尾部。

()获取并移除此队列的头,如果此队列为空,则返回null。

public static void main(String[] args) {ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();queue.offer("哈哈哈");System.out.println("offer后,队列是否空?" + queue.isEmpty());System.out.println("从队列中poll:" + queue.poll());System.out.println("pool后,队列是否空?" + queue.isEmpty());}offer是往队列添加元素,poll是从队列取出元素并且删除该元素执⾏结果offer后,队列是否空?false从队列中poll:哈哈哈pool后,队列是否空?trueConcurrentLinkedQueue中的add() 和 offer() 完全⼀样,都是往队列尾部添加元素还有个取元素⽅法peek()获取但不移除此队列的头;如果此队列为空,则返回nullpublic static void main(String[] args) {ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();queue.offer("哈哈哈");System.out.println("offer后,队列是否空?" + queue.isEmpty());System.out.println("从队列中peek:" + queue.peek());System.out.println("从队列中peek:" + queue.peek());System.out.println("从队列中peek:" + queue.peek());System.out.println("pool后,队列是否空?" + queue.isEmpty());}执⾏结果:offer后,队列是否空?false从队列中peek:哈哈哈从队列中peek:哈哈哈从队列中peek:哈哈哈pool后,队列是否空?falseremove( o)从队列中移除指定元素的单个实例(如果存在)public static void main(String[] args) {ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();queue.offer("哈哈哈");System.out.println("offer后,队列是否空?" + queue.isEmpty());System.out.println("从队列中remove已存在元素:" + queue.remove("哈哈哈"));System.out.println("从队列中remove不存在元素:" + queue.remove("123"));System.out.println("remove后,队列是否空?" + queue.isEmpty());}remove⼀个已存在元素,会返回true,remove不存在元素,返回false执⾏结果:offer后,队列是否空?false从队列中remove已存在元素:true从队列中remove不存在元素:falseremove后,队列是否空?truesize or isEmpty()返回此队列中的元素数量注意:如果此队列包含的元素数⼤于 Integer.MAX_VALUE,则返回 Integer.MAX_VALUE。

java并发包提供的三种常用并发队列实现

java并发包提供的三种常用并发队列实现

java并发包提供的三种常⽤并发队列实现java并发包中提供了三个常⽤的并发队列实现,分别是:ConcurrentLinkedQueue、LinkedBlockingQueue和ArrayBlockingQueue。

ConcurrentLinkedQueue使⽤的是CAS原语⽆锁队列实现,是⼀个异步队列,⼊队速度很快,出队进⾏了加锁,性能稍慢;LinkedBlockingQueue也是阻塞队列,⼊队和出队都⽤了加锁,当队空的时候线程会暂时阻塞;当队空的时候线程会暂时阻塞;ArrayBlockingQueue是初始容器固定的阻塞队列,我们可以⽤来作为数据库模块成功竞拍的队列,⽐如有10个商品,那么我们就设定⼀个10⼤⼩的数组队列。

⼀、BlockingQueue接⼝BlockingQueue接⼝定义了⼀种阻塞的FIFO queue,每⼀个BlockingQueue都有⼀个容量,让容量满时往BlockingQueue中添加数据时会造成阻塞,当容量为空时取元素操作会阻塞。

⼆、ArrayBlockingQueueArrayBlockingQueue是⼀个由数组⽀持的有界阻塞队列。

在读写操作上都需要锁住整个容器,因此吞吐量与⼀般的实现是相似的,适合于实现“⽣产者消费者”模式。

三、LinkedBlockingQueueLinkedBlockingQueue内部维持着⼀个数据缓冲队列(该队列由⼀个链表构成),当⽣产者往队列中放⼊⼀个数据时,队列会从⽣产者⼿中获取数据,并缓存在队列内部,⽽⽣产者⽴即返回;只有当队列缓冲区达到最⼤值缓存容量时(LinkedBlockingQueue可以通过构造函数指定该值),才会阻塞⽣产者队列,直到消费者从队列中消费掉⼀份数据,⽣产者线程会被唤醒,反之对于消费者这端的处理也基于同样的原理。

⽽LinkedBlockingQueue之所以能够⾼效的处理并发数据,还因为其对于⽣产者端和消费者端分别采⽤了独⽴的锁来控制数据同步,这也意味着在⾼并发的情况下⽣产者和消费者可以并⾏地操作队列中的数据,以此来提⾼整个队列的并发性能。

并发队列总结

并发队列总结

并发队列总结并发Queue并发队列在JDK提供了两套实现,⼀个是以ConcurrentLinkedQueue为代表的⾼性能队列,⼀个是以BlockingQueue接⼝为代表的阻塞队列,⽆论哪⼀种都会继承Queue接⼝。

ComcurrentLinkedQueueComcurrentLinkedQueue:是⼀个适⽤于⾼并发场景下的队列,通过⽆锁的⽅式,实现了⾼并发状态下的⾼性能,通常ComcurrentLinkedQueue性能要⾼于BlockingQueue.它是基于链接节点的⽆界线程安全队列。

改队列的元素遵循先进先出的原则,该队列不允许null元素ComcurrentLinkedQueue重要⽅法add()和offer()都是加⼊元素的⽅法(ComcurrentLinkedQueue中两个⽅法没有什么区别)poll()和peak()都是取头节点,区别是前者会删除元素,后者不会。

BlockingQueue常⽤⽅法offer:如果可能的话,将anObject加到BlockingQueue⾥,即如果BlockingQueue可以容纳,则返回ture,否则返回false。

(本⽅法不阻塞当前执⾏的⽅法的线程)offer(E o,long timeout,TimeUnit unit),可以设定等待的时间,如果在指定时间内,还不能往队列⾥加⼊BlockingQueue,则返回失败put(anObject):把anObejct加⼊到BlockingQueue⾥,如果BlockingQueue没有空间,则调⽤此⽅法的线程被阻断直到BlockingQueue⾥⾯有空间再继续。

poll(long timeout,TimeUnit unit):从BlockingQueue取出⼀个对⾸的对象,如果在指定时间内,队列⼀旦有数据可取,则⽴即返回队列中的数据。

否则知道时间超时还没有数据可取,则返回失败。

take():取⾛BlockingQueue⾥排在⾸位的对象,若BlockingQueue为空,阻断写⼊等待状态直到BlockingQueue有新的数据被加⼊drainTo():⼀次性从BlockingQueue获取所有可⽤的数据对象(还可以指定获取数据的个数),通过该⽅法,可以提升获取数据的效率,不需要多次分批加锁或者释放锁。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue在入队操作高并发性能比较并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue在入队操作高并发性能比较2011-01-19 08:522802人阅读测试结果显示:阻塞队列和并发队列在高并发情况下,性能相差不大。

1 Test.java代码参考/arkblue/archive/2011/01/14/6138598.aspx[ja va] view plaincopyprint?public class ConcurrentQueueTest {private static int COUNT = 100000;private static int THREAD_NUM = 10;private static CyclicBarrierThread cyclicBarrierThread = new CyclicBarrierThread();private static ConcurrentLinkedQueue conQueue = newConcurrentLinkedQueue();private static LinkedBlockingQueue linkQueue = new LinkedBlockingQueue();static class ConcurrentLinkedQueueProducer extends Test {public ConcurrentLinkedQueueProducer(String id, CyclicBarrier barrier,long count, int threadNum, ExecutorService executor) { super(id, barrier, count, threadNum, executor);}@Overrideprotected void test() {conQueue.add(1);}}static class LinkedBlockingQueueProducer extends Test {public LinkedBlockingQueueProducer(String id, CyclicBarrier barrier,long count, int threadNum, ExecutorService executor) { super(id, barrier, count, threadNum, executor);}@Overrideprotected void test() {conQueue.add(1);}}static class CyclicBarrierThread extends Thread {@Overridepublic void run() {conQueue.clear();linkQueue.clear();}}public static void test(String id, long count, int threadNum, ExecutorService executor) {final CyclicBarrier barrier = new CyclicBarrier(threadNum + 1,cyclicBarrierThread);System.out.println("==============================") ;System.out.println("count = " + count + "/t" + "Thread Count = "+ threadNum);concurrentTotalTime += new ConcurrentLinkedQueueProducer( "ConcurrentLinkedQueueProducer", barrier, COUNT, threadNum,executor).startTest();linkedBlockingTotalTime += new LinkedBlockingQueueProducer( "LinkedBlockingQueueProducer ", barrier, COUNT, threadNum,executor).startTest();totalThreadCount += threadNum;executor.shutdownNow();System.out.println("==============================")}static long concurrentTotalTime = 0;static long linkedBlockingTotalTime = 0;static long totalThreadCount = 0;public static void main(String[] args) throws InterruptedException {for (int i = 1; i 20; i++) {ExecutorService executor =Executors.newFixedThreadPool(THREAD_NUM* i);test("", COUNT, 10 * i, executor);}System.out.println("ConcurrentLinkedQueue Avg Time = " + concurrentTotalTime / totalThreadCount);System.out.println("LinkedBlockingQueue Avg Time = " + linkedBlockingTotalTime / totalThreadCount);} public class ConcurrentQueueTest {private static int COUNT = 100000;private static int THREAD_NUM = 10;private static CyclicBarrierThread cyclicBarrierThread = new CyclicBarrierThread(); private static ConcurrentLinkedQueue conQueue = new ConcurrentLinkedQueue();private static LinkedBlockingQueue linkQueue = new LinkedBlockingQueue(); static class ConcurrentLinkedQueueProducer extends Test { public ConcurrentLinkedQueueProducer(String id, CyclicBarrier barrier,long count, int threadNum, ExecutorService executor) {super(id, barrier, count, threadNum, executor);} @Overrideprotected void test() {conQueue.add(1);}} static class LinkedBlockingQueueProducer extends Test { public LinkedBlockingQueueProducer(String id,CyclicBarrier barrier,long count, int threadNum, ExecutorService executor) {super(id, barrier, count, threadNum, executor);} @Overrideprotected void test() {conQueue.add(1);}} static class CyclicBarrierThread extends Thread { @Overridepublic void run() {conQueue.clear();linkQueue.clear();}} public static void test(String id, long count, int threadNum,ExecutorService executor) { final CyclicBarrier barrier = new CyclicBarrier(threadNum + 1,cyclicBarrierThread);System.out.println("============================= =");System.out.println("count = " + count + "/t" + "ThreadCount = "+ threadNum); concurrentTotalTime += new ConcurrentLinkedQueueProducer("ConcurrentLinkedQueueProducer", barrier, COUNT, threadNum,executor).startTest();linkedBlockingTotalTime += new LinkedBlockingQueueProducer("LinkedBlockingQueueProducer ", barrier, COUNT, threadNum,executor).startTest(); totalThreadCount += threadNum;executor.shutdownNow();System.out.println("============================= =");} static long concurrentTotalTime = 0;static long linkedBlockingTotalTime = 0; static long totalThreadCount = 0; public static void main(String[] args) throws InterruptedException {for (int i = 1; i < 20; i++) {ExecutorService executor =Executors.newFixedThreadPool(THREAD_NUM* i);test("", COUNT, 10 * i, executor);} System.out.println("ConcurrentLinkedQueue Avg Time = "+ concurrentTotalTime / totalThreadCount);System.out.println("LinkedBlockingQueue Avg Time = "+ linkedBlockingTotalTime / totalThreadCount);}}结果,执行100,000次的并发入队操作,并发队列需要49毫秒,阻塞队列需要53毫秒,比阻塞队列平均快4毫秒。

相关文档
最新文档