`

【Java核心-进阶】并发工具包——线程安全的 List、Map、Set

    博客分类:
  • Java
 
阅读更多

三大并发类:Concurrent、CopyOnWrite、Blocking

Java并发包中的集合从线程安全实现方式而言可分为三类:Concurrent、CopyOnWrite、Blocking。

  • Concurrent 类的集合基于 lock-free 的方式实现。严格来说,它们是真正的并发。适合实现较高的吞吐量。
  • CopyOnWrite 类的集合顾名思义,会在该变集合的操作中拷贝原数据,并用新的内部集合对象替换原内部对象。
  • Blocking 类的集合则通过锁(ReentrantLock)实现。它们会提供 “等待性” 的方法。

Concurrent 的代价

虽然 Concurrent 类的集合没有 CopyOnWrite 那么中的修改开销,但这是有代价的:

  • Concurrent 集合的遍历一致性较弱
    在利用迭代器遍历时,如果容器发生修改,迭代器可以继续进行遍历,不会抛出 ConcurrentModificationException。
    在 HashMap 中则会抛出此异常(也就是 fail-fast 机制)
  • 因为是弱一致性,所以 size 等操作未必准确
  • 读取的性能也具有不确定性

 

List

CopyOnWriteArrayList

CopyOnWrite 是指对该集合的任何修改操作都会:拷贝原数组,修改后替换原数组;以此达到线程安全的目的。
这种数据结构适合 读多写少 的场景。因为修改开销比较大。

可直接查看其 add() 方法了解实现原理:

public boolean add(E e) {
  final ReentrantLock lock = this.lock;
  lock.lock();
  try {
    Object elements = getArray();
    int len = elements.length;
    // 拷贝原数组
    Object[] newElements = Array.copyOf(elements, len + 1);
    newElements[len] = e;
    // 替换原数组(引用)
    setArray(newElements);
    return true;
  } finally {
    lock.unlock();
  }
}

 

Map

ConcurrentHashMap vs ConcurrentSkipListMap

  • ConcurrentHashMap 的存取速度更快
  • ConcurrentSkipListMap 的元素是经过排序的(它实现了接口 SortedMap)

为什么 HashMap 有对应的 ConcurrentHashMap,而 TreeMap 没有对应的 ConcurrentTreeMap ?
TreeMap 也实现了接口 SortedMap,它的元素也是经过排序的,为什么又造出一个 ConcurrentSkipListMap?
因为 TreeMap 内部基于复杂的红黑树,很难在并发场景中实现进行合理粒度的同步
SkipList 的内部结构更简单,实现增删元素时的线程安全开销更小;但是会占用更多空间

 

Set

不存在的 ConcurrentHashSet

不知道为啥没有一个对应的 ConcurrentHashSet。
虽然可以通过JDK自带的 Collections.newSetFromMap() 方法创建一个基于 ConcurrentHashMap 的线程安全 Set。
但是一般来说有一个对称的语义是比较好的设计。HashMap - HashSet, ConcurrentHashMap - ConcurrentHashSet。

Guava 中的 Sets.newConcurrentHashSet() 内部就是通过上述方式实现的:

public static  Set newConcurrentHashSet() {
  return Collections.newSetFromMap(new ConcurrentHashMap<E, Boolean>());
}

ConcurrentSkipListSet

就像 HashSet 和 HashMap 的关系,ConcurrentSkipListSet 内部用 ConcurrentSkipListMap 实现(value 为 Boolean.TRUE)

CopyOnWriteArraySet

CopyOnWriteArraySet 内部用 CopyOnWriteArrayList 实现。
适用于数据量很少,且读操作远远多于写操作的情况。在遍历的时候应避免多个线程操作其引用。

 

我想要线程安全的 LinkedHashMap

LinkedHashMap 经常被用于实现 LRU缓存(Least Recently Used)。
很遗憾的是JDK中没有对应的线程安全实现。对性能要求高的场景中,Collections.synchronizedMap() 之类的外层一刀切式同步方案又不合适。
这时可以考虑一个第三方的实现方案:guava 的 CacheBuilder。例:

Map<String, String> cache = CacheBuilder.newBuilder()
    .maximumSize(100)
    .<String, String>build()
    .asMap();

 

POM依赖:

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>28.0-jre</version>
</dependency>

 

分享到:
评论

相关推荐

    2011.06 - Java语言程序设计-进阶篇(原书第8版

    在Java进阶篇中,会详细介绍List、Set、Map等集合类型的使用场景、性能特点及其提供的各种操作方法。 3. 泛型编程:泛型是Java SE 5版本中引入的一个重要特性,它允许在编译时提供类型安全检查,同时避免了类型转换...

    Java语言程序设计-进阶篇-原书第8版

    7. 多线程编程:理解Java中的线程机制,包括创建和管理线程,线程同步,以及并发工具类的使用,如Executor框架、锁(Locks)和条件变量(Conditions)。 8. 数据库编程:使用JDBC进行数据库操作,包括连接数据库,...

    Java语言程序设计-进阶篇第8版2011

    集合框架包含了List、Set、Map等常用的数据结构,掌握它们对于处理数据至关重要。 ### 异常处理与错误管理 异常处理是每个Java开发者都必须掌握的技能。本书可能包括如何正确地使用try-catch-finally语句来处理...

    Java 语言程序设计-进阶篇(原书第10版).pdf

    书中可能详细讲解List、Set、Map接口以及其实现类的特性,如ArrayList、LinkedList、HashSet、HashMap等。此外,还会涉及集合的并发处理,如ConcurrentHashMap和CopyOnWriteArrayList。 I/O流和NIO(非阻塞I/O)...

    Java语言程序设计-进阶篇%28原书第8版

    3. **集合框架**:Java集合框架是Java库的核心部分,涵盖了List、Set、Map等接口及其实现类,如ArrayList、HashSet、HashMap等。进阶学习会涉及这些集合的高级用法,如泛型、并发容器以及Stream API的使用。 4. **...

    java程序设计进阶版

    2. **集合框架**:Java集合框架包括List、Set、Map等接口及其实现类,如ArrayList、LinkedList、HashSet、HashMap等。深入学习它们的特性和应用场景,以及并发安全的集合类如ConcurrentHashMap。 3. **IO流与NIO**...

    Java_Collection_List-Set-Map.zip_list set map

    在Java编程语言中,集合框架是处理对象组的重要工具,主要包括List、Set和Map三大接口。这些接口由Java Collection Framework提供,它是一个统一的架构,用于存储和操作各种类型的对象。接下来,我们将深入探讨这三...

    Java实用编程源码50例-迅速提高编程技巧-供初学者学习——供高手参考

    5. **集合框架**:Java集合框架包括List、Set、Queue和Map等接口及其实现类,如ArrayList、HashSet和HashMap。源码中可能包含这些数据结构的使用,有助于理解它们的工作原理和应用场景。 6. **多线程**:Java内置了...

    Java-list-set-map.zip_Java list

    在Java编程语言中,集合框架是处理对象组的重要工具,其中`List`、`Set`和`Map`是三大核心接口。本资料“Java list set map.zip”专注于讲解这些接口及其相关实现,帮助开发者深入理解Java集合类的使用。 首先,`...

    由浅入深学Java-基础、进阶与必做

    10. 集合框架:Java集合框架提供了多种集合类,用于存储对象的集合,并且学习如何使用它们,如List、Set、Map等。 进阶知识点: 1. 泛型:泛型提供了一种方法,使得可以在编译时检查类型安全,并且减少类型转换。 ...

    2019最新java视频教程从基础到进阶到精通

    Java集合框架主要包括List、Set、Map三种类型的容器,用于存储和操作不同类型的对象集合。 #### 4. 泛型 泛型是Java 5引入的新特性,允许在编译时检查类型安全,并且所有的强制转换都是自动和隐式的,提高了代码的...

    精通Java--JDK、数据库系统开发、Web开发基础与实例

    数据集合部分会涵盖Java集合框架,包括List、Set、Queue、Map等各种接口和实现类,以及泛型、迭代器、比较器等相关概念。这部分内容有助于读者在实际开发中高效地管理和操作数据。 网络编程章节则会讲解Java的...

    2020老杜最新Java零基础进阶视频教程-常用类课件

    - 线程同步机制包括`synchronized`关键字、`wait()`、`notify()`和`notifyAll()`方法,以及`java.util.concurrent`包中的高级并发工具。 8. **反射机制**: - 反射允许在运行时检查类的信息(如方法、字段、构造...

    Java进阶.zip

    集合框架是Java标准库的重要部分,包括List、Set、Map等接口及其实现。深入理解它们的底层实现,如ArrayList与LinkedList的区别,HashMap与TreeMap的性能特性,有助于写出更高效和灵活的代码。 6. **I/O与NIO**: ...

    Java 7编程高级进阶

    6. **改进的并发工具(Fork/Join框架)** Java 7引入了Fork/Join框架,这是一个并行计算模型,适用于可以分解为子任务的问题。`java.util.concurrent.ForkJoinPool`和`java.util.concurrent.RecursiveTask`是其核心...

    java-util-1.3.1.jar.zip

    1. **集合框架扩展**:可能包含对Java内置集合类(如List、Set、Map)的增强,提供更高效的操作,例如快速排序、线程安全的实现等。 2. **日期和时间处理**:提供更加灵活和强大的日期时间操作,弥补Java 8之前的...

    JAVA架构师进阶之路核心知识整理.pdf

    多线程和并发是现代编程中的关键概念,涉及到线程的创建、生命周期、同步机制(如synchronized、ReentrantLock)以及并发工具类(如CountDownLatch、CyclicBarrier、Semaphore等)。 ### Spring原理 Spring框架作为...

    java常用代码工具包

    2. **集合操作**:Java集合框架是其核心特性之一,工具包可能包含对List、Set、Map等集合的扩展操作,如快速查找、排序、去重等高效算法。 3. **IO与网络**:工具包可能封装了读写文件、处理流、进行HTTP请求等网络...

    JAVA核心知识点整理.zip

    4. **集合框架**:Java集合框架包括接口(如List、Set、Map)和实现类(如ArrayList、LinkedList、HashSet、HashMap等)。学习它们的使用和区别,以及迭代器、泛型等概念,能帮助你高效地管理数据。 5. **输入/输出...

    2020老杜最新Java零基础进阶视频教程-集合课件

    此外,Hashtable是早期的线程安全Map实现,但由于其较低的性能,现在已经较少使用。Properties类是Map的一个特殊例子,专门用于存储键值对,其中键和值都是字符串。 集合框架还包含了一些辅助类,如Collections工具...

Global site tag (gtag.js) - Google Analytics