被变态的面试官折磨过吗?必须的,这篇就来说说那些面试官常问的所谓原理!同样的,遇到了就会上来更新,并不会立马写完O(∩_∩)O嗯!
一、介绍
- 所谓原理
- 原理这个词字我这里理解有下面几层意思:
- 代码的执行流程;
- 怎么实现的;
- 看了上面的解释有没有想打我的冲动?如何解释呢?
- 执行流程:基本上就会牵扯到一些设计模式之类的问题;
- 实现原理:看名字就知道会牵扯到一些数据结构方面的知识;
- 所以呢,面试的时候如果被问到这类问题,就想想问到的问题具有上面的哪个特征,有哪个,说哪个,两个都有就全说。 (@ο@) 哇~
- 原理这个词字我这里理解有下面几层意思:
二、常见原理类问题解析
- synchronized底层是怎么实现的?参考
- 实现方式:
- synchronized修饰的代码块:底层使用monitorenter和monitorexit指令完成代码块锁的实现;
- synchronized修饰的方法:底层使用ACC_SYNCHRONIZED标识完成方法锁的实现;
-
锁的四种状态:无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态;这四个状态随着竞争的激烈而逐渐升级;注意:锁可以升级但是不可降级,这种策略是为了提高获得锁和释放锁的效率;
- 偏向锁:引入偏向锁的目的和引入轻量级锁的目的很像,他们都是为了没有多线程竞争的前提下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗。轻量级锁和偏向锁不同的是:轻量级锁在无竞争的情况下使用 CAS 操作去代替使用互斥量,而偏向锁在无竞争的情况下会把整个同步都消除掉。偏向锁的“偏”就是偏心的偏,它的意思是会偏向于第一个获得它的线程,如果在接下来的执行中,该锁没有被其他线程获取,那么持有偏向锁的线程就不需要进行同步!但是对于锁竞争比较激烈的场合,偏向锁就失效了,因为这样场合极有可能每次申请锁的线程都是不相同的,因此这种场合下不应该使用偏向锁,否则会得不偿失。
- 轻量级锁:倘若偏向锁失败,虚拟机并不会立即升级为重量级锁,它还会尝试使用一种称为轻量级锁的优化手段(JDK1.6引入)。轻量级锁不是为了代替重量级锁,它的本意是在没有多线程竞争的前提下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗,因为使用轻量级锁时,不需要申请互斥量。另外,轻量级锁的加锁和解锁都用到了CAS操作。注意:轻量级锁能够提升程序同步性能的条件是“对于绝大部分锁,在整个同步周期内都是不存在竞争的”,这是一个经验数据。如果没有竞争,轻量级锁使用 CAS 操作避免了使用互斥量操作的开销。但如果存在锁竞争,除了互斥量开销外,还会额外发生CAS操作,因此在有锁竞争的情况下,轻量级锁比传统的重量级锁更慢!如果锁竞争激烈,那么轻量级将很快膨胀为重量级锁!
- 自旋锁和自适应自旋锁
- 扩展:
- monitor,这里指的是监视器锁,这个底层锁依赖于操作系统的 Mutex Lock 来实现的,Java 的线程是映射到操作系统的原生线程之上的。如果要操作一个线程(如:挂起或者唤醒),都需要操作系统帮忙完成,而操作系统实现线程之间的切换时需要从用户态转换到内核态,这个状态之间的转换需要相对比较长的时间,时间成本相对较高,这也是为什么早期的 synchronized 效率低的原因;JDK6中对synchronized关键字进行了相当大的优化。对锁的实现引入了大量的优化,如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销。
- 查看Java的汇编指令:
javap -c -s -v -l <class-name>.class
- 实现方式:
网友评论