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区别的更多相关文章

  1. HashMap/Hashtable/ConcurrentHashMap区别

    HashMap:每个隔间都没锁门,有人想上厕所,管理员指给他一个隔间,里面没人的话正常用,里面有人的话把这个人赶出来然后用. 优点,每个人进来不耽误都能用:缺点,每一个上厕所的人都有被中途赶出来的危险 ...

  2. [Java集合] 彻底搞懂HashMap,HashTable,ConcurrentHashMap之关联.

    注: 今天看到的一篇讲hashMap,hashTable,concurrentHashMap很透彻的一篇文章, 感谢原作者的分享. 原文地址: http://blog.csdn.net/zhanger ...

  3. 彻底搞懂HashMap,HashTable,ConcurrentHashMap之关联.

    注: 今天看到的一篇讲hashMap,hashTable,concurrentHashMap很透彻的一篇文章, 感谢原作者的分享.  原文地址: http://blog.csdn.net/zhange ...

  4. Java 集合 HashMap & HashSet 拾遗

    Java 集合 HashMap & HashSet 拾遗 @author ixenos 摘要:HashMap内部结构分析 Java HashMap采用的是冲突链表方式 从上图容易看出,如果选择 ...

  5. HashMap & HashTable的区别

    HashMap & HashTable的区别主要有以下: 1.HashMap是线程不安全的,HashTable是线程安全的.由这点区别可以知道,不考虑线程安全的情况下使用HashMap的效率明 ...

  6. Java集合和数组的区别

    参考:Java集合和数组的区别 集合和容器都是Java中的容器. 区别 数组特点:大小固定,只能存储相同数据类型的数据 集合特点:大小可动态扩展,可以存储各种类型的数据   转换 数组转换为集合: A ...

  7. Java集合——HashMap、HashTable以及ConCurrentHashMap异同比较

    0. 前言 HashMap和HashTable的区别一种比较简单的回答是: (1)HashMap是非线程安全的,HashTable是线程安全的. (2)HashMap的键和值都允许有null存在,而H ...

  8. hashmap,hashTable concurrentHashMap 是否为线程安全,区别,如何实现的

    线程安全类 在集合框架中,有些类是线程安全的,这些都是jdk1.1中的出现的.在jdk1.2之后,就出现许许多多非线程安全的类. 下面是这些线程安全的同步的类: vector:就比arraylist多 ...

  9. java集合HashMap、HashTable、HashSet详解

    一.Set和Map关系 Set代表集合元素无序,集合元素不可重复的集合,Map代表一种由多个key-value组成的集合,map集合是set集合的扩展只是名称不同,对应如下 二.HashMap的工作原 ...

随机推荐

  1. Java学习介绍

    Java版本介绍 JavaME:微型版,用于开发小型设备.智能卡.移动终端应用(使用率较低) JavaSE:标准版,用于创建桌面应用(企业用JavaSE创建桌面应用较少) JavaEE:企业版,用于创 ...

  2. iOS笔记之UIKit_UILable

    UILabel*label3 = [[UILabel alloc]initWithFrame:CGRectMake(0, 60+10+60+10+60+10, 320, 60)]; label3.ba ...

  3. 用fastreport在进行多列打印时,默认是先行后列,如何改成先列后行排记录?

    例子程序中的6.fr3是在Page中设置 columns=2这样就是先行后列,7.fr3就是3列先列后行的例子 1     6 2     7 3     8 4     9 5     10 但如果 ...

  4. Android-Throwable: A WebView method was called on thread 'JavaBridge'.

    错误详情: 01-30 03:36:52.441 12000-12048/cn.h5 D/@@@: e.ttt:java.lang.RuntimeException: java.lang.Throwa ...

  5. Aspose Word.Dll库自带的bug导致The document appears to be corrupted and cannot be loaded 问题处理。

    问题的详细描述: C#在开发过程中使用Aspose.word.dll库去实现word套打功能.但是,最近客户反映出现了一个问题,在打印文档的时候,系统报错.经过定位分析发现是Aspose.word.d ...

  6. Decimal类型截取保留N位小数向上取, Decimal类型截取保留N位小数并且不进行四舍五入操作

    Decimal类型截取保留N位小数向上取Decimal类型截取保留N位小数并且不进行四舍五入操作 封装静态方法 public class DecimalHelper { /// <summary ...

  7. ServiceStack DateTime数据类型转Json出现的困扰

    执行dotnet-new selfhost sstest 创建项目,然后打开解决方案 修改ssTest.ServiceModel中的Hello.cs,在HellopResponse中添加时间属性,然后 ...

  8. 装饰者模式&数据库连接池原理

    装饰者模式: 我是一个没有感情的杀手 在复习到自建数据库连接池的时候有点蒙了,再次翻看视频整理如下:(装饰者模式下自建数据库连接池修改close功能为 回收连接对象) 自备材料:数据库连接对象的获取的 ...

  9. 分布式锁实现思路及开源项目集成到springmvc并使用

    分布式锁顾名思义就是在分布式系统下的锁,而使用锁的唯一目的就是为了防止多个请求同时对某一个资源进行竞争性读写 在使用多线程时,为了让某一资源某一时刻只能有一个操作者,经常使用synchronized, ...

  10. 浅谈ES6原生Promise

    浅谈ES6原生Promise 转载 作者:samchowgo 链接:https://segmentfault.com/a/1190000006708151 ES6标准出炉之前,一个幽灵,回调的幽灵,游 ...