关于Lock与synchronized关键字在锁的处理上的重要差别

  • 锁的获取方式:前者是通过程序代码的方式由开发者手工获取,后者是通过JVM来获取(无需开发者干预)
  • 具体实现方式:前者是通过Java代码的方式来实现,后者是通过JVM底层来实现 (无需开发者关注)
  • 锁的释放方式:前者务必通过unlock()方法在finally块中手工释放,后者是通过JVM来释放(无需开发者关注)
  • 锁的具体类型:前者提供了多种,如公平锁、非公平锁,后者与前者均提供了可重入锁

编译器对于锁的优化措施

锁消除

JIT编译器(Just In Time编译器)可以在动态编译同步代码时,使用一种叫做逃逸分析的技术,来通过该项技术判别程序中所使用的锁对象是否只被
一个线程所使用,而没有散布到其他线程当中;如果情况就是这样的话,那么JIT编译器在编译这个同步代码时就不会生成synchronized关键字所标识
的锁的申请与释放机器码,从而消除了锁的使用流程.

  1. public class MyTest4 {
  2. public void method() {
  3. Object object = new Object();
  4. synchronized (object) {
  5. System.out.println("hello world");
  6. }
  7. }
  8. }

锁粗化

JIT编译器在执行动态编译时,若发现前后相邻的synchronized块使用的是同一个锁对象,那么它就会把这几个synchronized块给合并为一个较大
的同步块,这样做的好处在于线程在执行这些代码时,就无需频繁申请与释放锁了,从而达到申请与释放锁一次,就可以执行完全部的同步代码块,从而
提升了性能.

  1. public class MyTest {
  2. private Object object = new Object();
  3. public void method() {
  4. synchronized (object) {
  5. System.out.println("hello world");
  6. }
  7. synchronized (object) {
  8. System.out.println("welcome");
  9. }
  10. synchronized (object) {
  11. System.out.println("person");
  12. }
  13. }
  14. }