深入理解并发Queue:ConcurrentLinkedQueue与BlockingQueue的性能与应用场景

[id_2022105562]

深入理解并发Queue:ConcurrentLinkedQueue与BlockingQueue的性能与应用场景

Jdk 在并发的队列上提供了两套实现。其中一套是以 ConcurrentLinkedQueue 为代表的高性能队列,另一套是以 BlockingQueue 接口为代表的阻塞队列。并且无论在哪种队列中,它们都继承自 Queue。

[id_1381112440]

ConcurrentLinkedQueue 概念理解

ConcurrentLinkedQueue 是一个适用于高并发场景的队列。它通过无锁的方式,实现了在高并发状态下的高性能。通常,ConcurrentLinkedQueue 的性能比 BlockingQueue 好。它是一个基于链接节点的无界线程安全队列。该队列的元素遵循先讲先出的原则。头是最先加入的,尾是最近加入的,该队列不允许null元素。

ConcurrentLinkedQueue重要方法:

Add()是加入元素的一种方法,在 ConcurrentLinkedQueue 中,Offer()也是加入元素的一种方法,并且这两个方法在该队列中没有任何区别。

Poll()能够取头元素节点,并且会删除该元素节点。Peek()也能够取头元素节点,不过它不会删除元素节点。

案例

public class 使用队列 ConcurrentLinkedQueue {
   
    public static void main(String[] args) throws Exception {
        高性能的队列,它是无阻塞且无界的,名为 ConcurrentLinkedQueue
        ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
        q.offer("a");
        q.offer("b");
        q.offer("c");
        q.offer("d");
        q.add("e");
        System.out.println("从头部取出元素,并从队列里删除 >> "+q.poll());    //a 从头部取出元素,并从队列里删除
        System.out.println("删除后的长度 >> "+q.size());    //4
        System.out.println("取出头部元素 >> "+q.peek());    //b
        System.out.println("长度 >> "+q.size());    //4
        }
}

打印结果:

从头部取出元素,并从队列里删除 >> a
删除后的长度 >> 4
取出头部元素 >> b
长度 >> 4

BlockingQueue接口

ArrayBlockingQueue 是基于数组的阻塞队列实现。在其内部,维护着一个定长数组,用于缓存队列中的数据对象。它内部未实现读写分离,这意味着生产和消费不能完全并行。其长度需要定义,可以指定先讲先出或者先讲后出,也被称为有界队列,在很多场合都非常适合使用。

LinkedBlockingQueue 是基于链表的阻塞队列。它同 ArrayBlockingQueue 类似,内部维持着一个由链表构成的数据缓冲队列。LinkedBlockingQueue 能高效处理并发数据,是因为其内部实现采用了分离锁,即读写分离两个锁,这样能实现生产者和消费者操作的完全并行运行。并且它是一个无界队列。

SynchronousQueue 是一种没有缓冲的队列。生产者产生的数据会直接被消费者获取。并且会被消费者直接消费。

PriorityBlockingQueue 是基于优先级的阻塞队列。其优先级的判断是通过构造函数传入的 Compator 对象来决定的,这意味着传入队列的对象必须实现 Comparable 接口。在实现 PriorityBlockingQueue 时,内部控制线程同步的锁采用的是公平锁,并且它还是一个无界的队列。

DelayQueue 是带有延迟时间的 Queue。在 DelayQueue 中,只有当元素指定的延迟时间到达时,才能从队列中获取到该元素。DelayQueue 中的元素必须实现 Delayed 接口。它是一个没有大小限制的队列,应用场景较为广泛,例如可以用于移除缓存中超时的数据、处理任务超时情况以及关闭空闲连接等。

ArrayBlockingQueue 案例、LinkedBlockingQueue 案例、synchronousQueue 案例

public class UseQueue_ConcurrentLinkedQueue {
   
    public static void main(String[] args) throws Exception {
        System.out.println(ArrayBlockingQueue 是一种数据结构,它具有特定的特性和功能。它在多线程环境中被广泛使用,用于管理和协调线程之间的资源共享。这种队列的特点是基于数组实现,具有固定的大小,并且在插入和删除元素时遵循特定的规则。它可以提供高效的并发访问控制,确保线程安全地进行操作。在许多并发编程场景中,ArrayBlockingQueue 是一种常用的工具,用于实现生产者-消费者模式等。);
        //阻塞队列    有长度的队列
        ArrayBlockingQueue array = new ArrayBlockingQueue(5);
        array.put("a");
        array.put("b");
        array.add("c");
        array.add("d");
        array.add("e");
        //array.add("f");
        返回一个布尔类型,判断在 3 秒之内能否加入,若不能则返回 false。
System.out 会打印出 array 调用 offer 方法的结果。array 执行 offer 操作。array 进行 offer 动作。array 实施 offer 行为。array 做出 offer 举动。array 完成 offer 事宜。"a", 3, TimeUnit.SECONDS));
        System.out.println("所有数据  >>  " + array.toString());
        System.out.println("LinkedBlockingQueue 被提及。");
        //阻塞队列   无长度限制队列
        LinkedBlockingQueue q = new LinkedBlockingQueue();
        q.offer("a");
        q.offer("b");
        q.offer("c");
        q.offer("d");
        q.offer("e");
        q.add("f");
        System.out.println("总长度  >>  "+q.size());
        for使用迭代器进行遍历,首先获取到迭代器对象,即 (Iterator iterator = q.iterator());然后判断迭代器是否还有下一个元素,即 (iterator.hasNext());在有下一个元素的情况下进行相应操作。
获取迭代器的下一个元素,并将其转换为字符串类型赋值给字符串变量 string 。
            System.out.print(string+" -- ");
        }
        System.out.println();
        List list = new ArrayList();
        //在 q 的队列中取三个元素放到list 队列里
System.out 会打印出 q 把数据排入到 list 中的操作,并且指定了排入的数量为 。3));
        System.out.println(取出 LinkedBlockingQueue 中的数据,并将其放入 list 列表,此时 list 列表的长度为+list.size());
        for (String string : list) {
            System.out.print(string + " -- ");
        }
        System.out.println();
        System.out.println(SynchronousQueue 是一种特殊的队列。它具有独特的特性。在这种队列中,元素的插入和提取是同步进行的。它不存储任何元素。当一个线程试图插入一个元素时,如果没有其他线程正在等待提取元素,那么该线程将被阻塞,直到有线程等待提取元素。反之,当一个线程试图提取一个元素时,如果没有其他线程正在插入元素,那么该线程也将被阻塞,直到有线程插入元素。

你可能想看:
« 上一篇
下一篇 »

相关推荐

java中什么是冒泡,冒泡算法

2026年09月06日

27阅读

java中冒号,java双冒号

2026年09月06日

23阅读

java中的->,java中的是什么意思

2026年09月06日

24阅读

java中的super用法,Java中super的说明

2026年09月06日

27阅读

java中反射的应用,java中反射的应用场景

2026年09月06日

23阅读

java中开关的定义,Java关键字有哪些

2026年09月06日

25阅读