java中有很多list,但是原生支持并发的并不多,我们在多线程的环境中如果想同时操作同一个list的时候,就涉及到了一个并发的过程,这时候我们就需要选择自带有并发属性的list,那么java中的并发list到底有哪些呢?今天要给大家介绍的是ArrayListCopyOnWriteArrayListConcurrentLinkedDeque这几个。

各种list的优缺点

当涉及到并发编程时,不同的 List 实现具有各自的优点和缺点。下面是对 ArrayListCopyOnWriteArrayListConcurrentLinkedDeque 的优缺点进行详细比较的描述:

ArrayList:

  • 优点:

    • 简单易用:ArrayList 是 Java 中最基本的动态数组,易于理解和使用。
    • 高效的随机访问:由于内部基于数组实现,因此具有良好的随机访问性能。
  • 缺点:
    • 非线程安全:ArrayList 不是线程安全的,当多个线程同时修改它时会出现竞态条件。
    • 需要外部同步:为了使 ArrayList 在多线程环境下安全,需要额外的同步措施,如使用 Collections.synchronizedList

CopyOnWriteArrayList:

  • 优点:

    • 线程安全:CopyOnWriteArrayList 是线程安全的,多个线程可以同时读取而不会出现问题。
    • 适用于读多写少的情况:由于写操作会复制整个数组,适用于读多写少的情况,例如日志记录。
  • 缺点:
    • 写操作开销大:每次写操作都会复制整个列表,因此写操作的开销较大,不适合高频写入操作。
    • 数据不是实时的:由于写操作的复制过程,读操作可能会看到旧数据,因此不适用于需要实时数据的场景。

ConcurrentLinkedDeque:

  • 优点:

    • 高并发:ConcurrentLinkedDeque 针对高并发读写进行了优化,适用于需要高并发处理的情况。
    • 低延迟:添加和删除操作的性能很好,不会导致锁争用。
  • 缺点:
    • 不支持随机访问:ConcurrentLinkedDeque 不支持随机访问元素,因为它是一个双端队列,只能从队头和队尾进行操作。
    • 不适用于所有场景:不适合需要随机访问的场景,例如需要根据索引查找元素的情况。

总的来说,选择哪种 List 实现取决于您的具体需求。如果您需要高度并发且读写操作相对平衡,ConcurrentLinkedDeque 可能是更好的选择。如果您主要进行读操作且能够容忍写操作的开销,CopyOnWriteArrayList 是一个不错的选择。如果您只在单线程环境下操作,ArrayList 可能是更简单的选择,但需要注意同步问题。

他们的实现原理

理解这些并发 List 实现的原理对于正确使用它们非常重要。以下是这些 List 的实现原理:

ArrayList:

  • 实现:ArrayList 基于动态数组实现。它内部维护一个对象数组,可以根据需要进行自动扩展。
  • 原理:ArrayList 支持随机访问,因为可以通过索引直接访问元素。添加元素时,它会检查容量是否足够,如果不够,会创建一个更大的数组并将元素复制到新数组中。这可能导致内部数组的重新分配和复制,因此在多线程环境下需要额外的同步来确保线程安全。

CopyOnWriteArrayList:

  • 实现:CopyOnWriteArrayList 也是基于数组实现的,但与普通的 ArrayList 不同,它在写操作时不直接修改现有数组,而是创建一个新的副本。
  • 原理:读操作在不需要锁的情况下并发执行,因为它们始终访问当前的数组。写操作会复制当前数组的内容到一个新数组上,然后执行修改操作。这确保了读操作不受写操作的影响。虽然写操作需要额外的内存和复制,但读操作非常高效,适用于读多写少的场景。

ConcurrentLinkedDeque:

  • 实现:ConcurrentLinkedDeque 是一个双端队列,它使用节点来连接元素。每个节点都包含一个元素和指向前一个和后一个节点的引用。
  • 原理:在多线程环境下,ConcurrentLinkedDeque 使用CAS(比较并交换)操作来实现并发。添加元素时,它会在队头或队尾创建新的节点,然后通过CAS操作将新节点连接到队列中。删除元素时,会通过CAS来更改节点的引用,以确保线程安全。由于没有全局锁,ConcurrentLinkedDeque 允许高并发的添加和删除操作,但不支持随机访问。

总之,这些并发 List 的实现原理都是为了在多线程环境下提供高并发性能和线程安全。不同的实现方式适用于不同的使用场景。

使用举例

在多线程Java应用程序中,处理数据的并发访问是一个常见的挑战。这里将介绍四种支持并发的容器:ArrayListCopyOnWriteArrayListConcurrentLinkedDeque的用法和代码实现。

ArrayList

使用示例

以下是一个使用ArrayList的示例:

List<String> arrayList = Collections.synchronizedList(new ArrayList<>());

// 添加元素
arrayList.add("元素1");
arrayList.add("元素2"); // 迭代元素
for (String element : arrayList) {
System.out.println(element);
}

CopyOnWriteArrayList

使用示例

下面是一个使用CopyOnWriteArrayList的示例:

CopyOnWriteArrayList<String> copyOnWriteArrayList = new CopyOnWriteArrayList<>();

// 添加元素
copyOnWriteArrayList.add("元素1");
copyOnWriteArrayList.add("元素2"); // 迭代元素
for (String element : copyOnWriteArrayList) {
System.out.println(element);
}

ConcurrentLinkedDeque

使用示例

ConcurrentLinkedDeque的使用示例如下:

ConcurrentLinkedDeque<String> concurrentLinkedDeque = new ConcurrentLinkedDeque<>();

// 添加元素
concurrentLinkedDeque.offer("元素1");
concurrentLinkedDeque.offer("元素2"); // 获取并移除元素
String element = concurrentLinkedDeque.poll();
System.out.println("取出元素:" + element);

选择最适合您的容器

在实际应用中,您应该根据需求选择最适合的容器。如果需要高并发的读取操作,可以考虑使用CopyOnWriteArrayList。如果需要高并发的添加和移除元素操作,可以使用ConcurrentLinkedDeque。最终,根据项目要求和性能需求来选择适当的容器。

总结

Java提供了多种支持并发的容器,如ArrayList、CopyOnWriteArrayList、ConcurrentLinkedDeque。了解它们的用法和性能特点对于编写高效的多线程程序至关重要。选择正确的容器可以显著提高应用程序的性能和可靠性。

更多内容请参考 www.flydean.com

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

java中有哪些并发的List?只知道一种的就太逊了的更多相关文章

  1. Java中的并发线程操作(只贴代码,内有注释)

    package com.thread1; public class LiffOff implements Runnable{ protected int countDown = 10; private ...

  2. Java进阶知识点7:不要只会写synchronized - JDK十大并发编程组件总结

    一.背景 提到Java中的并发编程,首先想到的便是使用synchronized代码块,保证代码块在并发环境下有序执行,从而避免冲突.如果涉及多线程间通信,可以再在synchronized代码块中使用w ...

  3. JAVA多线程和并发基础面试问答(转载)

    JAVA多线程和并发基础面试问答 原文链接:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-ans ...

  4. [转] JAVA多线程和并发基础面试问答

    JAVA多线程和并发基础面试问答 原文链接:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-ans ...

  5. JAVA多线程和并发基础面试问答

    转载: JAVA多线程和并发基础面试问答 多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一.在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对 ...

  6. 【多线程】JAVA多线程和并发基础面试问答(转载)

    JAVA多线程和并发基础面试问答 原文链接:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-ans ...

  7. (转)JAVA多线程和并发基础面试问答

    JAVA多线程和并发基础面试问答 原文链接:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-ans ...

  8. Java编程思想 - 并发

    前言 Q: 为什么学习并发? A: 到目前为止,你学到的都是有关顺序编程的知识,即程序中的所有事物在任意时刻都只能执行一个步骤. A: 编程问题中相当大的一部分都可以通过使用顺序编程来解决,然而,对于 ...

  9. Java分布式系统高并发解决方案

    对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题, 但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研 ...

  10. Java多线程和并发基础面试总结

    多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一.在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题.收藏起来,希望给予即将找 ...

随机推荐

  1. ConcurrentHashMap是如何实现的?

    众所周知 ConcurrentHashMap 是 HashMap 的多线程版本,HashMap 在并发操作时会有各种问题,比如死循环问题.数据覆盖等问题.而这些问题,只要使用 ConcurrentHa ...

  2. 图解VirtualBox安装CentOS 7

    VirtualBox简介 VirtualBox是由德国InnoTek软件公司出品的虚拟机软件,现在则由甲骨文公司进行开发,是甲骨文公司xVM虚拟化平台技术的一部分. VirtualBox提供用户在32 ...

  3. Bioconductor 中的 R 包安装教程

    Bioconductor 是一个基于 R 语言的生物信息软件包,主要用于生物数据的注释.分析.统计.以及可视化(http://www.bioconductor.org). 总所周知,Bioconduc ...

  4. RIP动态路由协议配置实验

    项目背景 规划与配置接口 IP地址 AR1: [AR1-GigabitEthernet0/0/0]ip address 20.0.1.1 24 [AR1-GigabitEthernet0/0/1]ip ...

  5. 用python SMTP发送简单邮件

    python SMTP发送邮件 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议 它是一组由源地址到目的地址传送邮件得规则,由它来控制信件的中转方式. Pyth ...

  6. Java 设计模式实战系列—工厂模式

    在 Java 开发中,对象的创建是一个常见的场景,如果对象的创建和使用都写在一起,代码的耦合度高,也不利于后期的维护.我们可以使用工厂模式来解决这个问题,工厂模式是一个创建型模式,将对象的创建和使用分 ...

  7. Thinkphp6 连接达梦数据库

    Thinkphp6 连接达梦数据库 这里使用 IDEA phpEnv PHP7.3 Thinkphp6 桌面操作系统:Windows11 虚拟机:VMware 服务器操作系统:银河麒麟 在虚拟机操作与 ...

  8. 一个C#跨平台的机器视觉和机器学习的开源库

    大家都知道OpenCV是一个跨平台的机器视觉和机器学习的开源库,可以运行在Linux.Windows.Android和Mac OS操作系统上,由C++开发. 今天给大家介绍一个用C#对OpenCV封装 ...

  9. 【Redis】八股文(一)

    什么是Redis 基于key-value存储结构的NoSQL数据库 提供了String, Map, Set, ZSet, List等多种数据类型 功能丰富:支持发布订阅模式,能够为数据设置过期时间,能 ...

  10. 【git】基于JGit通过ssh-url拉取指定commit-id的代码

    实现 1️⃣ pom依赖: <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>o ...