【每天10问】002 后端知识点 2022.02.16 周三

 

每天10问: 是一个系列,不代表一定是10问,可能只有3问,主要是 记录当天自己的 技术思考和收获等

 

 

 

  1.   问题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行并返回一个未初始化的对象。

 

      

上一篇:计算机基础


下一篇:Java多线程16-线程同步问题与演示案例