Java—并发容器

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: Java—并发容器

并发容器


并发原理

Java 提供的基础容器都是线程不安全的,如果并发条件下多个线程同时对一个容器中的数据进行操作,可能会导致各种意想不到的错误。

因此 Java 又提供了一些并发容器在多线程情况下使用,这些并发容器都位于 java.util.concurrent 包内,使用时需要进行导入。


List 接口

Vector 类(已过时)

【数组序列】和 ArrayList 类类似,实现了 List 接口。内部使用 Object 数组存储。

Vector 类内部所有方法都是同步(synchronized) 的,因此线程安全。但高并发场景下非常容易阻塞,性能很差。

CopyOnWriteArrayList 类

【数组序列】和 ArrayList 类类似,实现了 List 接口。内部使用 Object 数组存储。

CopyOnWriteArrayList 对读取操作不上锁,对写入操作上锁。写入操作通过创建数组的副本来实现,修改的内容写入副本后再替换原来的数据。

不允许同时写,但读操作和写操作不冲突,在多读的场合性能非常好。

ConcurrentLinkedQueue 类

【链表序列】和 LinkedList 类类似,实现了 List 以及 Deque 接口。内部使用双向链表存储。

ConcurrentLinkedQueue 类非阻塞,通过 CAS 算法实现线程安全,尝试更新数据时会对数据进行比对。高并发场景下如果加锁的代价很高,可以达到很好的性能。


BlockingQueue 接口

【阻塞队列】被广泛使用在“生产者-消费者”问题中,其原因是 BlockingQueue 提供了可阻塞的插入和移除的方法。当队列容器已满,生产者线程会被阻塞,直到队列未满;当队列容器为空时,消费者线程会被阻塞,直至队列非空时为止。

ArrayBlockingQueue 类

有界队列实现类,底层采用数组来实现。ArrayBlockingQueue 一旦创建,容量不能改变。其并发控制采用可重入锁来控制,不管是插入操作还是读取操作,都需要获取到锁才能进行操作。

LinkedBlockingQueue 类

PriorityBlockingQueue 类


Map 接口

HashTable 类(已过时)

【哈希表】和 HashMap 类类似,实现了 Map 接口。

HashTable 类内部所有方法都是同步(synchronized) 的,因此线程安全。但由于整个哈希存储区域共享一把锁,高并发场景下非常容易阻塞,性能很差。

ConcurrentHashMap 类

【哈希表】和 HashMap 类类似,实现了 Map 接口。

并发控制使用 synchronized 和 CAS 来操作,采取分段锁机制。synchronized 对哈希存储区域的每个 key 分别上锁,只锁定当前链表或红黑二叉树的首节点,这样只要不发生哈希冲突就不会产生并发,效率大大提升。

JDK 1.7 中, ConcurrentHashMap 类中包含静态内部类 Segment,继承于 ReentrantLock 类用来充当锁的角色,每个 Segment 对象守护若干个保存键值对的链表,共同构成 ConcurrentHashMap 实例中的数组。在 HashEntry 类中,key,hash 和 next 域都被声明为 final 型,value 域被声明为 volatile 型。由于 HashEntry 的 next 域为 final 型,所以新节点只能在链表的表头处插入。

JDK 1.8 中放弃了 Segment 臃肿的设计,取而代之的是采用Node + CAS + Synchronized来保证并发安全进行实现。

static final class HashEntry<K,V> {
       final K key;                       // 声明 key 为 final 型
       final int hash;                   // 声明 hash 值为 final 型
       volatile V value;                 // 声明 value 为 volatile 型
       final HashEntry<K,V> next;      // 声明 next 为 final 型
       HashEntry(K key, int hash, HashEntry<K,V> next, V value) {
           this.key = key;
           this.hash = hash;
           this.next = next;
           this.value = value;
       }
}Copy to clipboardErrorCopied
复制代码

普通容器转换

synchronizedList 方法

如果遇到多个线程操作同一个容器的场景,可以通过 Collections 工具类中的 synchronizedList 方法将其转换成线程安全的容器。

方法会被 synchronized 关键字重定义。



目录
相关文章
|
3月前
|
安全 Java 编译器
揭秘JAVA深渊:那些让你头大的最晦涩知识点,从泛型迷思到并发陷阱,你敢挑战吗?
【8月更文挑战第22天】Java中的难点常隐藏在其高级特性中,如泛型与类型擦除、并发编程中的内存可见性及指令重排,以及反射与动态代理等。这些特性虽强大却也晦涩,要求开发者深入理解JVM运作机制及计算机底层细节。例如,泛型在编译时检查类型以增强安全性,但在运行时因类型擦除而丢失类型信息,可能导致类型安全问题。并发编程中,内存可见性和指令重排对同步机制提出更高要求,不当处理会导致数据不一致。反射与动态代理虽提供运行时行为定制能力,但也增加了复杂度和性能开销。掌握这些知识需深厚的技术底蕴和实践经验。
79 2
|
3月前
|
安全 Java 调度
解锁Java并发编程高阶技能:深入剖析无锁CAS机制、揭秘魔法类Unsafe、精通原子包Atomic,打造高效并发应用
【8月更文挑战第4天】在Java并发编程中,无锁编程以高性能和低延迟应对高并发挑战。核心在于无锁CAS(Compare-And-Swap)机制,它基于硬件支持,确保原子性更新;Unsafe类提供底层内存操作,实现CAS;原子包java.util.concurrent.atomic封装了CAS操作,简化并发编程。通过`AtomicInteger`示例,展现了线程安全的自增操作,突显了这些技术在构建高效并发程序中的关键作用。
70 1
|
3月前
|
Java Linux Maven
java依赖冲突解决问题之容器加载依赖jar包如何解决
java依赖冲突解决问题之容器加载依赖jar包如何解决
|
19天前
|
存储 设计模式 分布式计算
Java中的多线程编程:并发与并行的深度解析####
在当今软件开发领域,多线程编程已成为提升应用性能、响应速度及资源利用率的关键手段之一。本文将深入探讨Java平台上的多线程机制,从基础概念到高级应用,全面解析并发与并行编程的核心理念、实现方式及其在实际项目中的应用策略。不同于常规摘要的简洁概述,本文旨在通过详尽的技术剖析,为读者构建一个系统化的多线程知识框架,辅以生动实例,让抽象概念具体化,复杂问题简单化。 ####
|
24天前
|
Java 数据库连接 数据库
如何构建高效稳定的Java数据库连接池,涵盖连接池配置、并发控制和异常处理等方面
本文介绍了如何构建高效稳定的Java数据库连接池,涵盖连接池配置、并发控制和异常处理等方面。通过合理配置初始连接数、最大连接数和空闲连接超时时间,确保系统性能和稳定性。文章还探讨了同步阻塞、异步回调和信号量等并发控制策略,并提供了异常处理的最佳实践。最后,给出了一个简单的连接池示例代码,并推荐使用成熟的连接池框架(如HikariCP、C3P0)以简化开发。
46 2
|
1月前
|
Java
【编程进阶知识】揭秘Java多线程:并发与顺序编程的奥秘
本文介绍了Java多线程编程的基础,通过对比顺序执行和并发执行的方式,展示了如何使用`run`方法和`start`方法来控制线程的执行模式。文章通过具体示例详细解析了两者的异同及应用场景,帮助读者更好地理解和运用多线程技术。
29 1
|
1月前
|
消息中间件 NoSQL Kafka
Flink-10 Flink Java 3分钟上手 Docker容器化部署 JobManager TaskManager Kafka Redis Dockerfile docker-compose
Flink-10 Flink Java 3分钟上手 Docker容器化部署 JobManager TaskManager Kafka Redis Dockerfile docker-compose
43 4
|
1月前
|
Kubernetes Cloud Native 流计算
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
76 3
|
2月前
|
Java API 容器
JAVA并发编程系列(10)Condition条件队列-并发协作者
本文通过一线大厂面试真题,模拟消费者-生产者的场景,通过简洁的代码演示,帮助读者快速理解并复用。文章还详细解释了Condition与Object.wait()、notify()的区别,并探讨了Condition的核心原理及其实现机制。
|
3月前
|
存储 Java
Java 中 ConcurrentHashMap 的并发级别
【8月更文挑战第22天】
55 5
下一篇
无影云桌面