Java中HashMap 和 ConcurrentHashMap

`HashMap` 和 `ConcurrentHashMap` 都是 Java 中用来存储键值对的集合类,但它们有不同的设计目标,适用于不同的场景。以下是它们的详细对比和介绍。

### 1. `HashMap` 概述
`HashMap` 是基于哈希表的非同步集合类,主要用于在单线程环境下存储键值对。

#### 特性:
- **线程不安全**:`HashMap` 不是线程安全的,多个线程同时操作时可能会导致数据不一致的问题。如果需要在多线程环境中使用,可以手动进行同步或者使用同步包装器(例如 `Collections.synchronizedMap()`)。
- **允许 `null` 键和值**:`HashMap` 允许一个 `null` 键和多个 `null` 值。
- **性能优越**:由于没有同步开销,在单线程环境下,`HashMap` 的性能非常好。
- **无序**:元素的存储顺序是无序的,不能保证插入的顺序。

#### 示例代码:
```java
import java.util.HashMap;

public class HashMapExample {
    public static void main(String[] args) {
        HashMap<String, Integer> map = new HashMap<>();
        map.put("Alice", 25);
        map.put("Bob", 30);
        map.put(null, 100); // 允许null键
        map.put("Charlie", null); // 允许null值

        // 遍历HashMap
        for (String key : map.keySet()) {
            System.out.println(key + ": " + map.get(key));
        }
    }
}
```

### 2. `ConcurrentHashMap` 概述
`ConcurrentHashMap` 是 Java 5 引入的线程安全集合类,主要用于高并发环境下存储键值对。它通过分段锁(Java 8 之后采用 CAS 和少量锁)来确保线程安全,同时提供比 `Hashtable` 更高效的并发性能。

#### 特性:
- **线程安全**:`ConcurrentHashMap` 使用了一种更细粒度的锁机制(分段锁或 CAS 操作),保证线程安全且并发性能优越。在多线程下允许并发读写,而不会出现 `HashMap` 的数据一致性问题。
- **不允许 `null` 键和值**:与 `HashMap` 不同,`ConcurrentHashMap` 不允许 `null` 键或 `null` 值,插入 `null` 会抛出 `NullPointerException`。
- **高效并发**:通过分段锁或无锁(Java 8 之后的 CAS),多个线程可以同时访问不同的分段,降低了锁争用,提高了并发性能。
- **性能较好**:在高并发环境下,`ConcurrentHashMap` 的性能优于 `Hashtable`,因为它并不对整个 Map 加锁。

#### 示例代码:
```java
import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentHashMapExample {
    public static void main(String[] args) {
        ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
        map.put("Alice", 25);
        map.put("Bob", 30);
        // map.put(null, 100); // 不允许null键
        // map.put("Charlie", null); // 不允许null值

        // 遍历ConcurrentHashMap
        for (String key : map.keySet()) {
            System.out.println(key + ": " + map.get(key));
        }
    }
}
```

### 3. `HashMap` 与 `ConcurrentHashMap` 对比

| 特性                     | `HashMap`                          | `ConcurrentHashMap`                |
|--------------------------|------------------------------------|------------------------------------|
| **线程安全**             | 否,线程不安全                     | 是,线程安全                       |
| **允许 `null` 键和值**    | 允许 `null` 键和 `null` 值         | 不允许 `null` 键和值               |
| **同步机制**             | 无                                 | 分段锁或 CAS(无锁)               |
| **性能**                 | 在单线程环境下性能更优             | 在多线程环境下性能优越             |
| **适用场景**             | 单线程环境或非并发操作场景         | 多线程环境下的并发操作             |
| **迭代器行为**           | 迭代期间会抛出 `ConcurrentModificationException` | 迭代期间不抛异常,支持弱一致性     |
| **扩容机制**             | 负载因子达到 0.75 时扩容           | 负载因子达到 0.75 时扩容,线程安全 |

### 4. Java 8 对 `HashMap` 和 `ConcurrentHashMap` 的优化
- **`HashMap` 的优化**:在 Java 8 之前,`HashMap` 使用链表来处理哈希冲突,而在 Java 8 中,当链表长度超过一定阈值时,它会转换为红黑树结构来优化查询和插入操作。
- **`ConcurrentHashMap` 的优化**:Java 8 中的 `ConcurrentHashMap` 摒弃了原有的分段锁机制,而是采用了一种基于 CAS 和少量锁的方式来进一步提升并发性能。

### 5. `ConcurrentHashMap` 的分段锁原理(Java 7 之前)
在 Java 7 及之前的版本中,`ConcurrentHashMap` 使用了分段锁(Segmented Locking)机制。它将整个 `ConcurrentHashMap` 分为多个 Segment,每个 Segment 都是一个小的 `Hashtable`。多个线程可以同时访问不同的 Segment,实现并发访问。

在 Java 8 中,分段锁的实现被简化,使用 CAS 和少量的锁来优化性能,减少了锁的使用,提高了并发性能。

### 6. 总结
- **`HashMap`** 是在单线程环境中使用的高效集合类,允许 `null` 键和值,但在多线程环境中不安全。
- **`ConcurrentHashMap`** 是为高并发设计的线程安全集合类,不允许 `null` 键和值,适用于多线程环境,并提供更高效的并发性能。
- 在多线程场景下,**`ConcurrentHashMap`** 是替代 **`Hashtable`** 和 **同步化 `HashMap`** 的最佳选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/53588.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【车载开发系列】ParaSoft单元测试环境配置(一)

【车载开发系列】ParaSoft单元测试环境配置(一) ParaSoft单元测试环境配置 【车载开发系列】ParaSoft单元测试环境配置(一)一. 什么是bdf文件二. bdf文件构成三. 新规做成bdf文件四. 导入bdf文件创建测试工程五. 获取编译器信息六. 新增自定义编译器Step1:打开向导Step2:…

C和指针:标准函数库

整型函数 算术 <stdlib.h> int abs( int value); long int labs( long int value ); div_t div( int numerator, int denominator ); ldiv_t ldiv( long int numer,long int denom); abs 函数返回它的参数的绝对值. div 函数把它的第2个参数(分母)除以第1个参数(分子…

JAVA一键下单新鲜到家同城生鲜物流系统小程序源码

一键下单&#xff0c;新鲜到家 —— 探索同城生鲜物流系统的魅力 &#x1f69a; 一键下单&#xff0c;轻松享受便捷生活 在这个快节奏的时代&#xff0c;谁不想在忙碌之余还能轻松享受美食呢&#xff1f;&#x1f60b; "一键下单新鲜到家"的同城生鲜物流系统&#…

HTML5中IndexedDB前端本地数据库

一、indexedDB为何替代了Web SQL Database&#xff1f; 跟小朋友的教育从来没有什么“赢在起跑线”这种说法一样&#xff0c;在前端领域&#xff0c;也不是哪来先出来哪个就在日后引领风骚的。 HTML5 indexedDB和Web SQL Database都是本地数据库数据存储&#xff0c;Web SQL Da…

关于axios同步获取数据的问题

axios同步获取数据 Axios介绍问题代码修改 总结 Axios介绍 Axios 是一个基于 promise 网络请求库&#xff0c;作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 X…

[SCOI2014] 方伯伯的玉米田(dp+树状数组维护行列)

https://www.luogu.com.cn/problem/P3287 显然每次操作的区间一定是一个后缀 我们直接令 d p ( x , i ) dp(x,i) dp(x,i) 表示最后一个数是 x x x&#xff08;加之后&#xff09;&#xff0c;加了 i i i 次的最长长度&#xff0c;转移显然 max ⁡ d p ( y ≤ x , j ≤ i …

鸿蒙开发相册获取一张或多张照片,预览

import { photoAccessHelper } from kit.MediaLibraryKit; import { image } from kit.ImageKit; import { fileIo as fs } from kit.CoreFileKit;Entry Component struct Index {State getAlbum: string 显示相册中的图片;State pixelsArray : Array<image.PixelMap> |…

python测试开发---vue的常见指令

在 Vue.js 中&#xff0c;指令是用于在模板中绑定数据和 DOM 元素之间关系的特殊属性。指令通常以 v- 开头&#xff0c;后面跟上指令的名字。了解和使用这些指令是掌握 Vue.js 的关键之一。下面是一些 Vue.js 中常见的指令及其用法。 1. v-bind 作用&#xff1a;动态地绑定 H…

Spring Boot 集成 Redisson 实现消息队列

包含组件内容 RedisQueue&#xff1a;消息队列监听标识RedisQueueInit&#xff1a;Redis队列监听器RedisQueueListener&#xff1a;Redis消息队列监听实现RedisQueueService&#xff1a;Redis消息队列服务工具 代码实现 RedisQueue import java.lang.annotation.ElementTyp…

第2章 方法

本书作者起初以为仅靠研究命令行工具和指标就能提高性能。他认为这样不对。他从头到尾读了一遍手册&#xff0c;看懂了缺页故障、上下文切换和其他各种系统指标的定义&#xff0c;但不知道如何处理它们&#xff1a;如何从发现信号到找到解决方案。 他注意到&#xff0c;每当出…

18、公司信贷管理|贷款额度的测算|贷款期限及其定价的设定逻辑!

银行在综合权衡贷款的第一还款来源和第二还款来源、风险和收益的基础上&#xff0c;应明确提出贷与不贷的意见。经调查审查同意的贷款&#xff0c;应提出最终的融资方案。 合理的融资方案既要有利于提升本行的竞争力&#xff0c;又要有利于控制贷款风险。完整的融资方案一般包…

计算机网络 --- 【2】计算机网络的组成、功能

目录 一、计算机网络的组成 1.1 从组成部分看 1.2 从工作方式看 1.3 从逻辑功能看 1.4 总结 二、计算机网络的功能 2.1 数据通信 2.2 资源共享​编辑 2.3 分布式处理 2.4 提高可靠性 2.5 负载均衡 一、计算机网络的组成 1.1 从组成部分看 我们举例分析计算机网络从…

【人工智能学习笔记】4_4 深度学习基础之生成对抗网络

生成对抗网络&#xff08;Generative Adversarial Network, GAN&#xff09; 一种深度学习模型&#xff0c;通过判别模型&#xff08;Discriminative Model&#xff09;和生成模型&#xff08;Generative Model&#xff09;的相互博弈学习&#xff0c;生成接近真实数据的数据分…

19章 泛型

1.修改程序清单19-1中的GenericStack类&#xff0c;使用数组而不是ArrayList来实现它。你应该在给栈添加新元素之前检查数组的大小如果数组满了&#xff0c;就创建一个新数组。该数组是当前数组大小的两倍&#xff0c;然后将当前数组的元素复制到新数组中。 public class Gene…

​ArcGIS Pro和ArcGIS的10大区别

本文来源&#xff1a;水经注GIS公众号 如果你经常使用ArcGIS 进行制图和分析&#xff0c;那么你一定听说过ArcGIS Pro&#xff0c;这款软件是Esri未来主打的一款桌面GIS软件&#xff0c;那么这款软件和ArcGIS相比有什么不同呢&#xff0c;这里为你列举了两款软件的10大区别&am…

QScopedPointer的了解

QT 智能指针 QPointer QScopedPointer QSharedPointer QWeakPointer QSharedDataPointer 隐式共享 显示共享-CSDN博客 本文摘录自上面的文章 其类似于C11中的unique_ptr&#xff0c;用于管理动态分配的对象的独占所有权&#xff0c;即同一时间只能有一个QScopedPointer指向该…

Docker 安装 Nacos 教程

Nacos 是一个易于使用的平台&#xff0c;用于服务发现和配置管理。它支持服务的注册与发现&#xff0c;同时提供动态配置管理功能。本文将介绍如何使用 Docker 快速安装 Nacos&#xff0c;并提供相应的配置文件 standalone-mysql-5.7.yaml 用于设置 Nacos 与 MySQL 的集成。 参…

文本分类场景下微调BERT

How to Fine-Tune BERT for Text Classification 论文《How to Fine-Tune BERT for Text Classification?》是2019年发表的一篇论文。这篇文章做了一些实验来分析了如何在文本分类场景下微调BERT&#xff0c;是后面网上讨论如何微调BERT时经常提到的论文。 结论与思路 先来看…

Vue跨域问题、Vue配置开发环境代理服务、集成Axios发送Ajax请求、集成vue-resource发送Ajax请求

目录 1. Ajax请求服务介绍2. axios的安装3. Vue跨域问题介绍和解决方案4. 使用vue-cli配置开发环境代理服务4.1 简单配置4.2 复杂配置4.3 二次封装 5. 集成vue-resource发送Ajax请求 1. Ajax请求服务介绍 xhr: new XHLHttpRequest().open()/send()。偏向底层JQuery: 对xhr进行…

Sklearn的datasets模块与自带数据集介绍

datasets 模块 用 dir() 函数查看 datasets 模块的所有属性和函数 import sklearn.datasets as datasets# 列出 sklearn.datasets 模块中的所有属性和函数 print(dir(datasets)) datasets 模块下的数据集有三种类型&#xff1a; &#xff08;1&#xff09;load系列的经典数…