HashMap与Hashtable的区别
Hashtable:
1)键不可重复,值可以重复,底层哈希表,线程安全的。key和value都不允许为null。
HashMap:
实现:HashMap<K,V> extends AbstractMap<K,V>
键不可重复,值可以重复,线程不安全。允许key和value为null。
构造函数:HashMap():初始容量16,加载因子为0.75。
HashMap(int initialCapctity):初始容量自定义,加载因子0.75。
HashMap(int initialCapctity, float loadFactor):初始容量和加载因子都可以自定义。
加载因子:加载因子的系数小于等于1,意指 即当 元素个数 超过 容量长度*加载因子的系数 时,进行扩容。默认为0.75。即表示列表中元素的填满程度,是冲突机会与空间利用率的一种平衡。
数据结构:数组实现,每个位置用链表实现,即数组+链表,当链表长度超过9时转化成红黑树。
public HashMap(int initialCapacity, float loadFactor) { //初始容量不能<0 if (initialCapacity < 0) throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity); //初始容量不能 > 最大容量值,HashMap的最大容量值为2^30 if (initialCapacity > MAXIMUM_CAPACITY) initialCapacity = MAXIMUM_CAPACITY; //负载因子不能 < 0 if (loadFactor <= 0 || Float.isNaN(loadFactor)) throw new IllegalArgumentException("Illegal load factor: " + loadFactor); // 计算出大于 initialCapacity 的最小的 2 的 n 次方值。 int capacity = 1; while (capacity < initialCapacity) capacity <<= 1; this.loadFactor = loadFactor; //设置HashMap的容量极限,当HashMap的容量达到该极限时就会进行扩容操作 threshold = (int) (capacity * loadFactor); //初始化table数组 table = new Entry[capacity]; init(); }
看上图源码,每新建一个HashMap时都会初始化一个数组table,table数组中元素为Entry节点。
static class Entry<K,V> implements Map.Entry<K,V> { final K key; V value; Entry<K,V> next; final int hash; /** * Creates new entry. */ Entry(int h, K k, V v, Entry<K,V> n) { value = v; next = n; key = k; hash = h; } ....... }
CurrentHashMap:
1)底层采用分段的数组+链表实现,线程安全,高效的HashMap实现。
2)通过把整个map分成N个segment,可以提供相同的线程安全,但是效率提升N倍,默认提升16倍。(读操作不加锁,由于hashentry的value变量是volatile的,能保证读到的最新值)。
3)CurrentHashMap允许多个改操作并发进行,其关键在于使用锁分离技术。
4)有些方法需要跨段,比如size()和containsValue().
5)扩容:段内扩容(段内元素超过该段对应的Entry数组长度的75%触发扩容,不会对整个map扩容),插入前检测不需要扩容,有效避免无效扩容。
CAS无锁算法
原文地址:https://www.cnblogs.com/hjdk05/p/11815515.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Linux内核调优
- pyhon smtplib库 实现插入图片邮件发送
- mysql insert or update与UQ索引
- 矿机排查实战
- SpringBoot 整合 SpringDataRedis
- SpringDataRedis 基本使用
- Spring Security 基础入门
- Spring Security 安全认证
- Spring Security 自定义登录页
- CAS 服务端部署
- Spring Security 权限控制
- vue动态组件的用法
- elementUI中checekBox实现全选和反选以及实现在input中输入空格出现label分割
- centos 安装git
- centos 挂载硬盘