每天10问: 是一个系列,不代表一定是10问,可能只有3问,主要是 记录当天自己的 技术思考和收获等
- 问题01:LinkedHashMap的底层也还是 数组吗? 普通的 HashMap有什么区别?
答: 是 数组+ 双向链表 (树化后是 红黑树),普通的 HashMap是 数组+单向链表, 具体可以查看 https://blog.****.net/weixin_30988079/article/details/112375182 ===={知识点} 1)【知识点 01】LinkedHashMap是HashMap的一个子类,底层实现基本上和HashMap一样,只是在原来的单链表的基础上改成了双向链表,这样做的目的是为了让它能够实现插入数据的排序。也就是说如果遍历整个LinkedHashMap时,是会按照插入数据的顺序来遍历数据的。 2)【知识点 02】: Map.Entry (以 HashMap这个具体实现为例)是 HashMap的静态内部类 Map.Entry
2.问题02【todo】:LinkedHashMap中 其中的一个构造方法中的 accessOrder字段传递 true时,每次get()操作都会把get到的那个元素的顺序放到最后
这样做的意义或者作用是什么呢?
TODO --待解答
3.问题02:Java的 volatile的底层原理和使用的方法是怎样的?
答:1)volatile的特点是: ① 保证了可见性 ② 不支持原子性 ③禁止指令重排,具体参考:https://blog.****.net/u012723673/article/details/80682208?utm_source=app&app_version=5.0.0
【原理】:在JVM底层volatile是采用“内存屏障”来实现的。加入volatile关键字时,会多出一个lock前缀指令,这个lock的前缀指令就相当于是 内存屏障。提供的3种功能,正好是 对应 禁止指令重排 和 变量的各线程的可见性。
4.问题04:单例模式的双重锁为什么要加volatile
public class TestInstance{ private volatile static TestInstance instance; public static TestInstance getInstance(){ //1 if(instance == null){ //2 synchronized(TestInstance.class){ //3 if(instance == null){ //4 instance = new TestInstance(); //5 } } } return instance; //6 } ==== 需要volatile关键字的原因是,在并发情况下,如果没有volatile关键字,在第5行会出现问题。instance = new TestInstance();可以分解为3行伪代码 a. memory = allocate() //分配内存 b. ctorInstanc(memory) //初始化对象 c. instance = memory //设置instance指向刚分配的地址 上面的代码在编译运行时,可能会出现重排序从a-b-c排序为a-c-b。在多线程的情况下会出现以下问题。当线程A在执行第5行代码时,B线程进来执行到第2行代码。假设此时A执行的过程中发生了指令重排序,即先执行了a和c,没有执行b。那么由于A线程执行了c导致instance指向了一段地址,所以B线程判断instance不为null,会直接跳到第6行并返回一个未初始化的对象。