Java中的不可变集合与同步集合详解
作者:从1前2有3个4人_706 | 来源:互联网 | 2024-12-20 15:34
本文将详细探讨Java中提供的不可变集合(如`Collections.unmodifiableXXX`)和同步集合(如`Collections.synchronizedXXX`)的实现原理及使用方法,帮助开发者更好地理解和应用这些工具。
在 Java 编程中,`Collections` 类提供了多种工具方法来创建不可变集合和同步集合。这两种集合类型在多线程环境和数据保护方面有着重要的应用。以下是它们的详细介绍。 ### 一、不可变集合(Unmodifiable Collections) #### 1. 实现原理 不可变集合通过包装一个已有的集合,并重写所有可能改变集合状态的方法来实现。如果尝试调用这些方法,将会抛出 `UnsupportedOperationException` 异常。以 `UnmodifiableList` 为例,其内部结构如下: ```java static class UnmodifiableList extends UnmodifiableCollection implements List { private static final long serialVersiOnUID= -283967356065247728L; final List extends E> list; UnmodifiableList(List extends E> list) { super(list); this.list = list; } public boolean equals(Object o) { return o == this || list.equals(o); } public int hashCode() { return list.hashCode(); } public E get(int index) { return list.get(index); } public E set(int index, E element) { throw new UnsupportedOperationException(); } public void add(int index, E element) { throw new UnsupportedOperationException(); } public E remove(int index) { throw new UnsupportedOperationException(); } // 其他方法省略... } ``` `UnmodifiableList` 继承自 `UnmodifiableCollection`,后者已经重写了所有可能改变集合状态的方法,使其抛出 `UnsupportedOperationException`。`UnmodifiableList` 进一步实现了 `List` 接口,并针对列表特有的方法进行了相应的处理。 #### 2. 使用示例 创建一个不可变列表的示例如下: ```java List list = new ArrayList<>(); list.add("aa"); list.add("bb"); List unmodifiableList = Collections.unmodifiableList(list); System.out.println(unmodifiableList); // 输出 [aa, bb] ``` 尝试向 `unmodifiableList` 添加元素会抛出 `UnsupportedOperationException` 异常。需要注意的是,`Collections.unmodifiableList` 创建的并不是真正的不可变集合,如果原始集合被修改,不可变集合的内容也会随之变化。 ```java list.add("cc"); System.out.println(unmodifiableList); // 输出 [aa, bb, cc] ``` ### 二、同步集合(Synchronized Collections) #### 1. 实现原理 同步集合通过在每个方法调用时添加同步锁来实现线程安全。以 `SynchronizedCollection` 为例,其内部结构如下: ```java static class SynchronizedCollection implements Collection, Serializable { private static final long serialVersiOnUID= 3053995032091335093L; final Collection c; // 被包装的集合 final Object mutex; // 同步锁 SynchronizedCollection(Collection c) { this.c = Objects.requireNonNull(c); mutex = this; } SynchronizedCollection(Collection c, Object mutex) { this.c = Objects.requireNonNull(c); this.mutex = Objects.requireNonNull(mutex); } public int size() { synchronized (mutex) { return c.size(); } } public boolean isEmpty() { synchronized (mutex) { return c.isEmpty(); } } public boolean contains(Object o) { synchronized (mutex) { return c.contains(o); } } // 其他方法省略... } ``` `SynchronizedCollection` 在每个方法中使用 `synchronized` 关键字来确保线程安全。需要注意的是,某些方法(如 `iterator`)返回的迭代器本身并不是线程安全的,需要用户手动同步。 #### 2. 使用示例 创建一个同步列表的示例如下: ```java List list = new ArrayList<>(); List synchrOnizedList= Collections.synchronizedList(list); ``` 虽然 `Collections.synchronizedList` 提供了基本的线程安全,但在某些情况下,同步容器仍然可能遇到并发问题,例如在迭代过程中修改集合可能会导致 `ConcurrentModificationException` 异常。因此,在多线程环境中使用同步集合时,需要额外注意这些潜在的问题。
推荐阅读
本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ...
[详细]
蜡笔小新 2024-12-28 10:51:55
本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ...
[详细]
蜡笔小新 2024-12-27 15:06:12
本文详细介绍了 Apache Jena 库中的 Txn.executeWrite 方法,通过多个实际代码示例展示了其在不同场景下的应用,帮助开发者更好地理解和使用该方法。 ...
[详细]
蜡笔小新 2024-12-26 17:55:52
Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ...
[详细]
蜡笔小新 2024-12-28 08:54:34
本文详细介绍了如何构建一个高效的UI管理系统,集中处理UI页面的打开、关闭、层级管理和页面跳转等问题。通过UIManager统一管理外部切换逻辑,实现功能逻辑分散化和代码复用,支持多人协作开发。 ...
[详细]
蜡笔小新 2024-12-27 10:28:40
本文探讨了如何优化和正确配置Kafka Streams应用程序以确保准确的状态存储查询。通过调整配置参数和代码逻辑,可以有效解决数据不一致的问题。 ...
[详细]
蜡笔小新 2024-12-26 18:17:14
本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ...
[详细]
蜡笔小新 2024-12-26 17:45:48
主要用了2个类来实现的,话不多说,直接看运行结果,然后在奉上源代码1.Index.javaimportjava.awt.Color;im ...
[详细]
蜡笔小新 2024-12-27 18:18:10
在前两篇文章中,我们探讨了 ControllerDescriptor 和 ActionDescriptor 这两个描述对象,分别对应控制器和操作方法。本文将基于 MVC3 源码进一步分析 ParameterDescriptor,即用于描述 Action 方法参数的对象,并详细介绍其工作原理。 ...
[详细]
蜡笔小新 2024-12-27 15:26:10
本文介绍了如何在 Android 中创建一个自定义的渐变圆环加载控件,该控件已在多个知名应用中使用。我们将详细探讨其工作原理和实现方法。 ...
[详细]
蜡笔小新 2024-12-27 13:34:19
本周开发笔记重点介绍了在新项目中使用MQTT协议进行硬件连接的技术细节,涵盖其特性、原理及实现步骤。 ...
[详细]
蜡笔小新 2024-12-27 11:30:44
本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ...
[详细]
蜡笔小新 2024-12-27 10:18:13
本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ...
[详细]
蜡笔小新 2024-12-26 17:37:25
蜡笔小新 2024-12-26 13:29:32
本文详细介绍了 Java 中 org.apache.xmlbeans.SchemaType 类的 getBaseEnumType() 方法,提供了多个代码示例,并解释了其在不同场景下的使用方法。 ...
[详细]
蜡笔小新 2024-12-26 11:46:55
从1前2有3个4人_706
这个家伙很懒,什么也没留下!