-
互斥锁
-
读写锁
-
公平锁、非公平锁
-
可重入锁
-
自旋锁
-
分段锁
-
锁升级(无锁|偏向锁|轻量级锁|重量级锁)
-
锁优化技术(锁粗化、锁消除)
-
更多详细内容, 一文全面梳理各种锁机制
HashMap原理?
答案:内部由数组和链表组成,非线程安全。JDK1.7和1.8的主要区别在于头插和尾插方式的修改,头插容易导致HashMap链表死循环,并且1.8之后加入 红黑树
对性能有提升。
-
put插入:key 计算hash值,取模,找到数组位置,如果数组中没有元素直接存入,反之,则判断key是否相同,key相同就覆盖,否则就会插入到链表的尾部。如果链表的⻓度超过8且数据总量超过64,则会转换成
红黑树
。最后判断元素个数是否超过默认的⻓度(16)*负载因子(0.75),也就是12,超过则进行扩容。 -
get查询:计算出hash值,然后去数组查询,是红黑树就去红黑树查,链表就遍历链表查询就可以了。
红黑树的时间复杂度 O(logn);链表的时间复杂度 O(n),当链表过长时,红黑树能大大提高查询性能。
ConcurrentHashMap 如何能保证线程安全的?
答案:ConcurrentHashmap在JDK1.7和1.8的版本改动比较大。
-
1.7 使用Segment + HashEntry 分段锁的方式实现,
Segment
继承于ReentrantLock
,HashEntry
存储键值对数据。 -
1.8 采用数组+ 链表 + 红黑树。锁设计上抛弃了Segment分段锁,采用 CAS + synchronized 实现。
ArrayList 和 LinkedList 有什么区别?
答案:
1、Arraylist
-
非线程安全
-
底层采用数组存储
-
插入、删除元素,时间复杂度受位置影响。默认是添加在列表的末尾,如果在位置 k 插入或删除一个元素,需要将k后面的元素后移或前移一位。
-
支持随机访问,根据索引下标序号,可以快速定位元素
-
需要连续的内存空间,中间不能有碎片