常见面试1
目录
1. ConcurrentHashMap底层原理(jdk7 jdk8区别对比)
2. 线程创建方式有几种 具体列出
3. 数据库是如何实现悲观锁和乐观锁(说明具体实现过程)
4. CAS底层原理(说明Unsafe核心类)
1. ConcurrentHashMap底层原理(jdk7 jdk8区别对比)
jdk1.7 底层数据结构是数组+链表 jdk7中的ConcurrentHashMap由 Segment和HashEntry组成,即ConcurrentHashMap 把哈希桶数组切分成小数组(Segment),每个小数组有n个HashEntry组成.
jdk1.8中ConcurrentHashMap 选择了与hashMap相同的Node数组+链表+红黑树在锁上的实现上,抛弃了原有的Segment分段锁,采用CAS+Syncgronized实现更加细粒度的锁,将锁的级别控制在了更细粒度的哈希桶。
数组元素级别,只需要锁住这个链表头结点 红黑树和根节点 就不会影响其他的哈希桶数组元素的读写 大大提高了并发度
2. 线程创建方式有几种 具体列出
1.自定义类继承Thread基类 重写run方法, 没有返回值,单继承,但是不能抛出 checked exception,可以抛出运行时异常,error
2.自定义实现Runnable接口 重写run方法 ,没有返回值,多实现,但是不能抛出 checked exception,可以抛出运行时异常,error
3.自定义类实现callable接口 重写call方法,可以获取返回值,checked exception 显式处理的异常类型,必须try
4.线程池,概念:池化技术,资源复用思想,参数:设置核心线程数,最大线程数,时间单位,ms,指定工厂,任务队列,拒绝策略
3. 数据库是如何实现悲观锁和乐观锁(说明具体实现过程)
悲观锁 select for update 每次执行都需要判断锁的状态,他会悲观的认为当前状态是上锁状态,先判断,后执行。
乐观锁 select id version where version =version+1表示 每次执行都乐观的 任务当前,当前是没有上锁的状态,先执行,后判断
具体实现:在数据库中需要额外创建一个version字段,每次执行修改操作的时候,都需要判断版本号
先查询版本号,select * from 表名 where id =1;
将版本号作为修条件执行 update 表名 set price = 120.00 ,version = version+1 where id =1 and version =1;
更新语句中的version = version+1是关键 它将版本号加1 并且在where子句中确保只有当版本号匹配时才进行更新 如果版本号不匹配 取专刊信息后有其他回话已经修改了记录 此更新操作将不会生效
4. CAS底层原理(说明Unsafe核心类)
先获取unsafe对象,通过unsafe对象获取偏移量 目的是为了获取所对应的属性
调用unsafe.compareAndSwap (对象,偏移量,旧址,新值,)保证线程安全,是一种乐观锁的体现