Java编译器是否优化了空的同步块?
假设我在代码的某个地方写了一个空的Java编译器是否优化了空的同步块?,java,locking,compiler-optimization,Java,Locking,Compiler Optimization,假设我在代码的某个地方写了一个空的synchronized块: synchronized(obj){ //No code here } 因此,由于同步块不包含任何代码,JIT编译器是否会通过不锁定obj来优化它,因为它没有任何用处 Java编译器也有类似的技巧,比如锁粗化,但是这个同步块也会被优化吗 编辑: 根据亚西利亚斯的观点 synchronized(new Object()){ //empty block } JIT编译器现在是否能够对此进行优化,因为我使用的对象不会逃逸我
synchronized
块:
synchronized(obj){
//No code here
}
因此,由于同步块不包含任何代码,JIT编译器是否会通过不锁定obj
来优化它,因为它没有任何用处
Java编译器也有类似的技巧,比如锁粗化,但是这个同步块也会被优化吗
编辑:
根据亚西利亚斯的观点
synchronized(new Object()){
//empty block
}
JIT编译器现在是否能够对此进行优化,因为我使用的对象不会逃逸我的方法?这不能基于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语义仅指获取同一个锁的情况。@tbodt如果可以,他不会问。。。请告诉他如何“尝试”我只是把代码放在一个文件中,反编译了类文件,同步块仍然在那里,即使它是空的。@tbodt这不能证明什么。它可能会被JIT删除。另一个编译器/JVM可能会有不同的行为等等。@Tala IMHO了解编译器在后台的功能,这会让你成为更好的程序员。@tbodt查看字节码很少能证明什么。不用麻烦了。@assylias我也会在问题中加上:)这一点很好,因为在这种情况下,也不会有可见性保证。@assylias你和我的答案变得难以区分:)@MarkoTopolnik我认为这是一种恭维!因此,如果我们使用synchronized(mutex){}
,其中mutex
是一个共享变量(类的一个字段),我们可以安全地假设这个锁定提供的可见性保证,对吗?我的意思是,没有锁省略happens@Alupkers要么另一个线程获得相同的锁并获得保证,要么它没有也没有得到保证。每当JIT编译器能够证明另一个线程不可能获得相同的锁时,它就可以从它输出的机器代码中删除它。如果无法证明,它将输出相应的内存限制。