1、集合框架
Collection ArrayList、LinkedList;
Set HashSet
Map HashMap、ConcurrentHashMap
ArrayList:底层是数组,初始化时数据量是0,add时默认变成10;每次扩容是它之前容量的1.5倍
LinkedList: 底层是带有头结点和尾节点的双向链表;提供两种插入方式:头插LinkedFirst;尾插LinkedLast;查询量大的话比较慢
线程安全又想使用List:用Vector,和ArrayList一样底层是数组;大部分方法被synchronized修饰;线程安全,扩容大小两倍
HashMap:单链表和红黑树的转换:单链表长度大于等于8(并且hash桶大于等于64)时,将单链表转换为红黑树形式存储;红黑树的节点数量小于等于6时重新转换成一个单链表;
hash桶的数量:默认16个,阈yu值默认是0.75;影响扩容;
扩容:首先检测数组里元素个数,loadFactor负载因子0.75,桶数默认是16,阈值是16*0.75=12;当哈希桶占用的容量大于12时,会触发扩容,扩容成之前哈希桶容量的两倍,同乘2的N次幂,把之前的元素在进行一次哈希运算,添加到新的hash桶中,按照链表或者红黑树的方式再排列起来;
插入操作的时候多线程会有数据覆盖的可能;1.7时Put的时候还有一次Resize的过程,这个过程会造成头插形成一个环形链表从而形成死循环;1.8改成尾插;
可用concurrentHashMap、HashTable、Collection.Synchronized来替代;性能与对比
ConcurrentHashMap:1.7-分片数组,为了保证线程安全有个Segment锁,Segment继承于ReentrantLock,每次只给一段加锁来保证它的并发度;1.8改成和hashmap一样的数据结构(数组+单链表/红黑树),逐渐放弃分片锁机制,使用synchronized和CAS(1.6后)
分段锁如何找到具体的值,需要几次hash
CAS(compare & swap):轻量级加锁过程,在并发量不打 or 锁竞争不激烈的情况下修改值,先查;再修改;在写之前比较与之前的结果有无区别,有区别说明线程不安全;无区别时可修改,无需加锁;改善性能;会有ABA问题:之前读和过段时间读中间会被第三人修改过但又改回来了,可以通过添加戳或标志位来解决不被篡改