涉及面试题:
1. synchronized常用的使用方法有哪些:
1)修饰代码块,指定对象加锁,对对象加锁
2)修饰实例方法,对当前实例对象加锁
3)修饰静态方法,对当前类的Class字节码对象加锁(所有通过该类new出来的实例对象都要同步,用的是同一个锁)
2. synchronized锁升级(jdk1.6对synchronized底层做了那些优化)
1)无锁态 -> 偏向锁 -> 轻量级锁 -> 重量级锁
偏向锁指不存在锁竞争,常常是一个线程多次获得通一个锁。偏向锁不需要重新加解锁。偏向锁适用于基本没有线程竞争锁的同步场景。
轻量级锁,存在锁竞争情况,偏向锁会升级为轻量级锁,竞争状态下没有抢到锁的线程会自旋而不会阻塞,长时间自旋会造成CPU消耗。适用于少量线程竞争锁对象,且锁的时间不长,追求响应速度的场景。
重量级锁,锁竞争情况严重时,某个达到最大自旋次数的线程,会将轻量级锁升级为重量级锁。重量级锁不会导致CPU空转消耗CPU,但是线程阻塞,响应时间长。适用于多线程竞争锁,且锁持有时间长,追求吞吐量的场景。
3. 乐观锁与悲观锁区别(synchronized是悲观锁)
乐观锁认为一般不会出现冲突,只会在更新数据的时候才会进行数据监测。
乐观锁的实现是CAS(compare and swap,对比替换)机制。
乐观锁存在ABA问题,解决方案为引入版本号,每次操作之后让版本号+1,比较的时候版本号和值都比较。
悲观锁:假设最坏的情况,每次拿数据的时候认为别人会修改,所以每次访问都要进行上锁。