一、HashTable与HashMap有啥区别?
- HashTable线程安全,不允许null值(key和value都不可以),HashMap线程非安全,允许null值(key和value都可以)
注意:key为空没有hashcode,无法计算hash值。
二、HashMap1.7和1.8的区别
- HashMap1.7底层采用数组+链表实现
- HashMap1.8底层采用数组+链表+红黑树实现
三、HashMap的put方法底层是如何实现的?
- 判断key为空的情况下,存放数组下标为0的位置,
默认HashMap的初始容量为16,加载因子大小16*0.75=12(当容量达到12时进行2倍扩容),
根据key计算hash值,存放在数组对应下标位置,
如果hash值相等且内容不等存放在同一个链表中,
如果当前size>加载因子阈值,开始2倍扩容。
四、HashMap1.8为什么引入红黑树呢?
- 如果index冲突过多,导致链表过长,因为链表时间复杂度是On,为了解决链表查询效率慢的问题,这时候链表长度大于8的情况下并且数组的容量大于64的情况下就开始将链表转成红黑树存放,这时候时间复杂度从O(n)变成O(logn).
五、线程安全和不安全:
- 线程安全:指多个线程在执行同一段代码的时候采用加锁机制,使每次的执行结果和单线程执行的结果都是一样的,不存在执行程序时出现意外结果。
- 线程不安全:是指不提供加锁机制保护,有可能出现多个线程先后更改数据造成所得到的数据是错误的,不完整的数据
举例说明:假如售票系统有1000张票,a和b同时来买票,如果是线程不安全,那么可能售票系统可能出现1000-1区同时执行的情况,最终结构是999而不是998张票。
六、解决多线程并发访问资源安全问题的方法:
- synchronized关键字,就是用来控制线程同步的,保证我们的线程在多线程环境下,不被多个线程同时执行,确保我们数据的完整性,使用方法一般是加在方法上。
- Lock是在java1.6被引进来,Lock的引入让锁有了可操作性,是指我们在需要的时候去手动的获取锁和释放锁,甚至我们还可以终端获取以及超时获取的同步特性,从使用上synchronize使用起来比Lock更方便。