是否由Java编译器优化了空的同步块?

时间:2013-08-05 10:36:24

标签: java locking compiler-optimization

假设在我的代码中某处我写了一个空的synchronized块:

synchronized(obj){
   //No code here
}

因为同步块不包含任何代码,JIT编译器是否会通过不锁定obj来优化它,因为它没用?

Java编译器做类似的技巧,例如Lock粗化,但是这个同步块也会被优化掉吗?

修改

根据assylias的观点,

synchronized(new Object()){
   //empty block
}

JIT编译器现在能够优化它,因为我使用的是一个不会逃避我的方法的Object吗?

1 个答案:

答案 0 :(得分:13)

这不能在Java Memory Model语义的基础上进行优化。锁获取 - 释放操作可能被其他东西替换,但即使是空的synchronized块也会对其他线程获取相同锁的操作的可见性产生影响。

具体来说,可以保证在释放锁之前由一个线程完成的所有写操作在获取相同的锁后对另一个线程可见。

关于你的编辑

这是一个非常不同的情况:在一个对象上获得一个锁,可以通过逃逸分析证明没有其他线程能够获取它。在这种情况下,synchronized块的内容是什么并不重要:该点仅在使用的锁中。代码可以看起来像你发布它,或者甚至像这样:

Object o = new Object();
synchronized(o) { 
   // any operations you like, as long as they don't let o escape the method scope
}

这可以通过称为 lock elision 的转换来执行:JVM可以假装它从未看到synchronized块。这是因为JMM语义仅指获取同一个锁的情况。