synchronized之前一直都是重量级的锁,性能差,但是后来java官方(jdk1.5还是1.6)对它进行了优化:针对 synchronized 获取锁的方式,JVM 使用了锁升级的优化方式,就是先使用偏向锁优先同一线程,然后再次获取锁,如果失败,就升级为 CAS 轻量级锁,如果失败就会短暂自旋,防止线程被系统挂起。最后如果以上都失败就升级为重量级锁。所以是一步步升级上去的,最初也是通过很多轻量级的方式锁定的(偏向锁–>CAS轻量级锁–>自旋–>重量级锁)。Java并发基础(四):Synchronized原理和锁优化升级过程_mingyuli的博客-CSDN博客
根据泊松分布,在负载因子默认为0.75的时候,单个hash槽内元素个数为8的概率小于百万分之一,所以将7作为一个分水岭,等于7的时候不转换,大于等于8的时候才进行转换,小于等于6的时候就化为链表。
原因1:这是因为ConcurrentHashMap和Hashtable都是支持并发的,这样会有一个问题,当你通过get(k)获取对应的value时,如果获取到的是null时,你无法判断,它是put(k,v)的时候value就为null,还是这个key从来没有做过映射。
而HashMap是非并发的,可以通过contains(key)来进行校验。而支持并发的Map在调用m.contains(key)和m.get(key)时m可能已经不同了
答:在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加、删除、修改),则会抛出 Concurrent Modification Exception。
答:迭代器在遍历时直接访问集合中的内容,在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变modCount的值。 每当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出Concurrent Modification Exception异常,终止遍历。 (注意:不能依赖于这个异常是否抛出而进行并发操作的判断,因为会有类似CAS操作的“ABA”问题,所以这个异常只建议用于检测并发修改的bug)。
3、什么是安全失败机制(fail—safe)呢?
答:采用安全失败机制的集合容器,在遍历时不是直接在集合上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。由于循环的时候是对原集合的“复制品”进行遍历,所以在你遍历的过程中对原集合的更改都不会被迭代器检测到,所以不会报错。
java.util包下的集合类都是快速失败(fail-fast)的,不能在多线程下发生并发修改(迭代过程中被修改)算是一种安全机制,但是预防不了ABA问题;
java.util.concurrent包下的容器都是安全失败(fail—safe),可以在多线程下并发使用,并发修改,不过要想适用于并发场景,需要额外的控制管理;
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/mingyuli/article/details/120469623
内容来源于网络,如有侵权,请联系作者删除!