1.偏向锁:
大多数情况下,多线程不存在多线程竞争,反而是同一个线程多次获得,为了让线程获得锁的代价更低点,引入了偏向锁。当一个线程访问同步块并获得锁时,会在对象头和栈帧中的锁记录里存储锁偏向的线程ID,以后该线程再次进入同步块时不需要通过CAS操作来加解锁,只要测试下对象头的mark word中是否存储了指向该线程的偏向锁,如果测试成功,则获取该对象的锁;如果测试失败,要再测试下Mark Work中偏向锁的标志是否设置为1;如果没有设置,则使用CAS去竞争锁;如果设置了,尝试使用CAS把对象头的偏向锁指向当前线程
偏向锁的释放:偏向锁使用了一种等到竞争出现才释放的机制。如果有线程来竞争,它会先暂停拥有偏向锁的线程,然后检查拥有偏向锁的线程是否还活着,如果线程不处于活动状态,则把对象头设置为无锁状态;如果线程还活着,拥有偏向锁的栈会被执行,遍历偏向锁的锁记录,栈中的锁记录和对象头中的Mark Word 要么重新偏向别的线程,要么设置为无锁,要么标记对象不适合做偏向锁,最后唤醒暂停的线程。

偏向锁的关闭:java1.6以上默认使用偏向锁,但是在应用启动几秒后激活,可以配置JVM参数来关闭延迟:-XX:BiasedLockingStartupDelay=0;如果你确定应用中的锁都是竞争锁,可以通过JVM参数关闭偏向锁:-XX:UseBiasedLocking=false;那么程序默认进入轻量级锁状态。
2.轻量级锁:
轻量级锁加锁:线程再执行同步块之前,JVM会在当前线程的栈帧中先创建存储锁记录的空间,并将对象头中的Mark Word复制到锁记录中,然后线程测试使用CAS把对象头中的Mark Word替换为指向锁记录的指针;如果成功了,则获取锁;如果失败了,表示其他线程竞争锁,当前线程便尝试自旋式获取锁(自旋锁就是不放弃cpu的时间片,原地等待获得锁的线程释放锁);
轻量级锁解锁:使用原则操作的CAS把Mark Word替换回到对象头,如果成功了,则表示没有竞争;如果失败,有竞争,轻量级锁变为重量级

因为自旋式会消耗cpu,为避免无效的自旋式(例如获得所得线程被阻塞了),一旦变为重量级锁,就不会恢复到轻量级。当锁处于该状态下,其他线程测试获取锁时,会被阻塞,当持有锁的线程释放了锁喉,会唤醒等待的线程,重新开始下一轮竞争。
3.锁的优缺点比较:
