6

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

synchronized(obj){
   //No code here
}

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

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

编辑:

根据 assylias 的观点,

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

JIT 编译器现在是否能够优化这一点,因为我正在使用一个不会逃避我的方法的对象?

4

1 回答 1

15

这不能基于 Java 内存模型语义进行优化。锁获取-释放操作可能会被其他东西代替,但即使是一个空synchronized块也会对获取相同锁的其他线程所采取的操作的可见性产生影响。

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

关于你的编辑

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

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

这可以通过称为锁省略的转换来执行:JVM 可以假装它从未看到该synchronized块。这是因为 JMM 语义只涉及获取同一个锁的情况。

于 2013-08-05T10:41:10.597 回答