Java集合——HashMap,HashTable,ConcurrentHashMap区别
Map:“键值”对映射的抽象接口。该映射不包括重复的键,一个键对应一个值。
SortedMap:有序的键值对接口,继承Map接口。
NavigableMap:继承SortedMap,具有了针对给定搜索目标返回最接近匹配项的导航方法的接口。
AbstractMap:实现了Map中的绝大部分函数接口。它减少了“Map的实现类”的重复编码。
Dictionary:任何可将键映射到相应值的类的抽象父类。目前被Map接口取代。
TreeMap:有序散列表,实现SortedMap 接口,底层通过红黑树实现。
HashMap:是基于“拉链法”实现的散列表。底层采用“数组+链表”实现。
WeakHashMap:基于“拉链法”实现的散列表。
HashTable:基于“拉链法”实现的散列表。
一 、HashMap
Java集合类是个非常重要的知识点,HashMap、HashTable、ConcurrentHashMap等算是集合类中的重点
1、HashMap是非线程安全的,HashTable是线程安全的。
2、HashMap的键和值都允许有null值存在,而HashTable则不行。
3、因为线程安全的问题,HashMap效率比HashTable的要高。
4、HashTable 基于synchronized锁,读写只能单线程访问,阻塞保证读写一致,多线程高并发下阻塞严重、效率低下
4、ConcurrentHashMap 高并发的、效率高,基于lock锁, concurrentLevel划分出了多个Segment来对key-value进行存储,默认16个线程无阻赛
缺点:有可能读写不一致,不一定能保证数据的完整性
Java中的另一个线程安全的与HashMap极其类似的类是什么?同样是线程安全,它与HashTable在线程同步上有什么不同?
二、HashTable的内部存储结构
HashTable和HashMap采用相同的存储机制,二者的实现基本一致,不同的是:
1、HashMap是非线程安全的,HashTable是线程安全的,内部的方法基本都是synchronized。
2、HashTable不允许有null值的存在。
在HashTable中调用put方法时,如果key为null,直接抛出NullPointerException。其它细微的差别还有,比如初始化Entry数组的大小等等,但基本思想和HashMap一样。
三、HashTable和ConcurrentHashMap的比较
ConcurrentHashMap是线程安全的HashMap的实现。同样是线程安全的类,它与HashTable在同步方面有什么不同呢?
synchronized关键字加锁的原理,其实是对对象加锁,不论你是在方法前加synchronized还是语句块前加,锁住的都是对象整体,
但是ConcurrentHashMap的同步机制和这个不同,它不是加synchronized关键字,而是基于lock操作的,这样的目的是保证同步的时候,锁住的不是整个对象。
事实上,ConcurrentHashMap可以满足concurrentLevel个线程并发无阻塞的操作集合对象。
ConcurrentHashMap基于concurrentLevel划分出了多个Segment来对key-value进行存储,从而避免每次锁定整个数组,在默认的情况下,允许16个线程并发无阻塞的操作集合对象,尽可能地减少并发时的阻塞现象。
在多线程的环境中,相对于HashTable,ConcurrentHashMap会带来很大的性能提升!
简单说下 synchronized 和lock的区别
synchronized是java中的一个关键字,也就是说是Java语言内置的特性。那么为什么会出现Lock呢? 在上面一篇文章中,我们了解到如果一个代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁,
而这里获取锁的线程释放锁只会有两种情况: 1)获取锁的线程执行完了该代码块,然后线程释放对锁的占有; 2)线程执行发生异常,此时JVM会让线程自动释放锁。 那么如果这个获取锁的线程由于要等待IO或者其他原因(比如调用sleep方法)被阻塞了,但是又没有释放锁,其他线程便只能干巴巴地等待,试想一下,这多么影响程序执行效率。 因此就需要有一种机制可以不让等待的线程一直无期限地等待下去(比如只等待一定的时间或者能够响应中断),通过Lock就可以办到。 再举个例子:当有多个线程读写文件时,读操作和写操作会发生冲突现象,写操作和写操作会发生冲突现象,但是读操作和读操作不会发生冲突现象。 但是采用synchronized关键字来实现同步的话,就会导致一个问题: 如果多个线程都只是进行读操作,所以当一个线程在进行读操作时,其他线程只能等待无法进行读操作。 因此就需要一种机制来使得多个线程都只是进行读操作时,线程之间不会发生冲突,通过Lock就可以办到。 另外,通过Lock可以知道线程有没有成功获取到锁。这个是synchronized无法办到的。 总结一下,也就是说Lock提供了比synchronized更多的功能。但是要注意以下几点: 1)Lock不是Java语言内置的,synchronized是Java语言的关键字,因此是内置特性。Lock是一个类,通过这个类可以实现同步访问; 2)Lock和synchronized有一点非常大的不同,采用synchronized不需要用户去手动释放锁,当synchronized方法或者synchronized代码块执行完之后,系统会自动让线程释放对锁的占用;
而Lock则必须要用户去手动释放锁,如果没有主动释放锁,就有可能导致出现死锁现象。
Java集合——HashMap,HashTable,ConcurrentHashMap区别的更多相关文章
- HashMap/Hashtable/ConcurrentHashMap区别
HashMap:每个隔间都没锁门,有人想上厕所,管理员指给他一个隔间,里面没人的话正常用,里面有人的话把这个人赶出来然后用. 优点,每个人进来不耽误都能用:缺点,每一个上厕所的人都有被中途赶出来的危险 ...
- [Java集合] 彻底搞懂HashMap,HashTable,ConcurrentHashMap之关联.
注: 今天看到的一篇讲hashMap,hashTable,concurrentHashMap很透彻的一篇文章, 感谢原作者的分享. 原文地址: http://blog.csdn.net/zhanger ...
- 彻底搞懂HashMap,HashTable,ConcurrentHashMap之关联.
注: 今天看到的一篇讲hashMap,hashTable,concurrentHashMap很透彻的一篇文章, 感谢原作者的分享. 原文地址: http://blog.csdn.net/zhange ...
- Java 集合 HashMap & HashSet 拾遗
Java 集合 HashMap & HashSet 拾遗 @author ixenos 摘要:HashMap内部结构分析 Java HashMap采用的是冲突链表方式 从上图容易看出,如果选择 ...
- HashMap & HashTable的区别
HashMap & HashTable的区别主要有以下: 1.HashMap是线程不安全的,HashTable是线程安全的.由这点区别可以知道,不考虑线程安全的情况下使用HashMap的效率明 ...
- Java集合和数组的区别
参考:Java集合和数组的区别 集合和容器都是Java中的容器. 区别 数组特点:大小固定,只能存储相同数据类型的数据 集合特点:大小可动态扩展,可以存储各种类型的数据 转换 数组转换为集合: A ...
- Java集合——HashMap、HashTable以及ConCurrentHashMap异同比较
0. 前言 HashMap和HashTable的区别一种比较简单的回答是: (1)HashMap是非线程安全的,HashTable是线程安全的. (2)HashMap的键和值都允许有null存在,而H ...
- hashmap,hashTable concurrentHashMap 是否为线程安全,区别,如何实现的
线程安全类 在集合框架中,有些类是线程安全的,这些都是jdk1.1中的出现的.在jdk1.2之后,就出现许许多多非线程安全的类. 下面是这些线程安全的同步的类: vector:就比arraylist多 ...
- java集合HashMap、HashTable、HashSet详解
一.Set和Map关系 Set代表集合元素无序,集合元素不可重复的集合,Map代表一种由多个key-value组成的集合,map集合是set集合的扩展只是名称不同,对应如下 二.HashMap的工作原 ...
随机推荐
- 分形在遥感和GIS中的应用
GIS等高线化简 遥感图像的追踪 分形matlab实现:分形应用于遥感图像处理 低分辨率和高分辨率图形它们的形状是相似的(图像增强) 贪吃蛇和蚁群算法:试想管中窥豹,一只小蚂蚁 ...
- Mac 下netstat和linux下不一样
Linux's netstat command options and OS X(/BSD)'s have almost nothing to do with each other. Of the o ...
- Idea使用拆解
收藏学习地址 https://blog.csdn.net/qq_28804275/article/details/80891907
- 普通用户开放 sudo 权限
大家都知道 linux 每个目录都是有权限的,所以如果要想在此目录下读写,则要有这个目录的权限,或者就是有 sudo 权限,那怎么给普通用户赋予 sudo 权限呢,下面我们来看一下: 1.先用 roo ...
- centos下添加epel源
RHEL以及他的衍生发行版如CentOS.Scientific Linux为了稳定,官方的rpm repository提供的rpm包往往是很滞后的,当然了,这样做这是无可厚非的,毕竟这是服务器版本,安 ...
- 在EF中使用Expression自动生成p=>new Entity(){X="",Y="",..}格式的Lambda表达式灵活实现按需更新
一.基本介绍 回忆:最早接触Expression是在学校接触到EF的时候,发现where方法里的参数是Expression<Func<T,bool>>这么一个类型,当 ...
- 【转】「Chris Richardson 微服务系列」微服务架构的优势与不足
Posted on 2016年5月4日 编者的话|本文来自 Nginx 官方博客,是微服务系列文章的第一篇,主要探讨了传统的单体式应用的不足,以及微服务架构的优势与挑战. 作者介绍:Chris Ric ...
- Jmeter_前端RSA加密下的登陆模拟_引用js文件实现
版权声明:本文为博主原创文章,未经博主允许不得转载. 在一次项目实战中,前端登录使用了RSA加密,使用LoadRunner压测的第一步,就是模拟用户登录,可惜loadRunner11并不能录制前端的加 ...
- Java内存溢出问题总结
使用Java那么久,在此总结一下Java中常见的内存溢出问题以及对应的解决思路 堆溢出 报错信息 java.lang.OutOfMemoryError: Java heap space 报错原因 堆中 ...
- a 便签实现 下载
如果想通过纯前端技术实现文件下载,直接把a标签的href属性设置为文件路径即可,如下: <a href="https://cdn.shopify.com/s/files/1/1545/ ...