- 博客(8)
- 收藏
- 关注
原创 线程的生命周期和状态
blocked:阻塞状态,需要等待锁释放,一般为被动触发。timeWaiting:超时等待状态,有等待时间的等待。new:初始状态,线程被创建,但是还未start()。runnable:运行状态,执行了start()方法。waiting:无期限的等待,一般为主动触发的等待。结束状态:线程结束。
2025-09-22 16:28:49
114
原创 HashMap的底层数据结构和扩容
初始化容量为16,负载因子默认为0.75,当hashMap的长度到达临界值12时会触发扩容,临界值 = 当前容量 * 负载因子。每次扩容时原长度的2倍。当链表长度大于等于8,并且hashMap的长度大于等于64时(如果小于64,则会先对数组进行扩容,不会转化为红黑树),会将链表转化为红黑树。jdk1.7之前底层数据结构使用的是数组加链表实现,jdk1.8之后使用的是数组加链表或红黑树组成。当红黑树长度等于6时,会退化为链表。
2025-09-20 11:46:52
165
原创 HashMap 多线程操作导致死循环问题
在多线程环境下扩容操作可能存在死循环问题,这是由于当一个桶位中有多个元素需要进行扩容时,多个线程同时对链表进行操作,头插法可能会导致链表中的节点指向错误的位置,从而形成一个环形链表,进而使得查询元素的操作陷入死循环无法结束。为了解决这个问题,JDK1.8 版本的 HashMap 采用了尾插法而不是头插法来避免链表倒置,使得插入的节点永远都是放在链表的末尾,避免了链表中的环形结构。但是还是不建议在多线程下使用。还是会存在数据覆盖的问题。并发环境下,推荐使用。JDK1.7 及之前版本的。
2025-09-18 22:14:30
260
原创 hashMap的长度为什么是2的幂次方?
1.可以更好的保证哈希值的均匀分布:扩容之后,在旧数组元素 hash 值比较均匀的情况下,新数组元素也会被分配的比较均匀,最好的情况是会有一半在新数组的前半部分,一半在新数组后半部分。这样也使得扩容机制变得简单和高效,扩容后只需检查哈希值高位的变化来决定元素的新位置,要么位置不变(高位为 0),要么就是移动到新位置(高位为 1,原索引位置+原容量)。方法和扰动函数)的情况下,新数组元素也会被分配的比较均匀,最好的情况是会有一半在新数组的前半部分,一半在新数组后半部分。,这里看的就是第五个二进制位。
2025-09-18 20:25:00
512
原创 arrayList扩容机制
底层是一个object数组,jdk1.7及以前初始容量为10,1.7之后初始为一个空数组,当插入第一个元素时容量为10,当插入超过10个元素时,扩容至原来的1.5倍,如果当前容量为偶数,则是1.5倍,如果是奇数,则丢弃小数位,为当前容量的1.5倍左右。
2025-09-18 12:28:00
158
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅
1