关于Lock与synchronized关键字在锁的处理上的重要差别
- 锁的获取方式:前者是通过程序代码的方式由开发者手工获取,后者是通过JVM来获取(无需开发者干预)
- 具体实现方式:前者是通过Java代码的方式来实现,后者是通过JVM底层来实现 (无需开发者关注)
- 锁的释放方式:前者务必通过unlock()方法在finally块中手工释放,后者是通过JVM来释放(无需开发者关注)
- 锁的具体类型:前者提供了多种,如公平锁、非公平锁,后者与前者均提供了可重入锁
编译器对于锁的优化措施
锁消除
JIT编译器(Just In Time编译器)可以在动态编译同步代码时,使用一种叫做逃逸分析的技术,来通过该项技术判别程序中所使用的锁对象是否只被
一个线程所使用,而没有散布到其他线程当中;如果情况就是这样的话,那么JIT编译器在编译这个同步代码时就不会生成synchronized关键字所标识
的锁的申请与释放机器码,从而消除了锁的使用流程.
public class MyTest4 {
public void method() {
Object object = new Object();
synchronized (object) {
System.out.println("hello world");
}
}
}
锁粗化
JIT编译器在执行动态编译时,若发现前后相邻的synchronized块使用的是同一个锁对象,那么它就会把这几个synchronized块给合并为一个较大
的同步块,这样做的好处在于线程在执行这些代码时,就无需频繁申请与释放锁了,从而达到申请与释放锁一次,就可以执行完全部的同步代码块,从而
提升了性能.
public class MyTest {
private Object object = new Object();
public void method() {
synchronized (object) {
System.out.println("hello world");
}
synchronized (object) {
System.out.println("welcome");
}
synchronized (object) {
System.out.println("person");
}
}
}