【问题标题】:What is the difference between synchronized(this) and synchronized method同步(this)和同步方法有什么区别
【发布时间】:2011-05-22 15:39:45
【问题描述】:

假设我们有这两个示例代码:

public synchronized void getSomething(){
     this.hello = "hello World";
}

还有这个

public void getSomething(){
   synchronized(this){
     this.hello = "hello World";
   }
}

那么有人可以告诉我现在有什么不同吗?

【问题讨论】:

    标签: java thread-safety


    【解决方案1】:

    这两种不同的方法在功能上是等效的可能有非常小的性能差异:

    在字节码级别,同步方法将同步的需要作为方法访问标志中设置的位来宣传。 JVM 查找该位标志并进行适当的同步。

    同步块通过存储在类文件的方法定义中的一系列字节码操作来实现其同步。

    因此,同步方法可能可能会执行得稍微快一些,并且占用更少的字节码空间。

    同样,按照规范,两者在功能上是相同的。

    我猜性能差异可以忽略不计,代码风格指南应该会胜出。一些编译器甚至可能将块优化为访问标志。 JIT 可能会消除性能差异。

    【讨论】:

      【解决方案2】:

      查看本文的这一部分:

      http://www.ibm.com/developerworks/ibm/library/it-haggar_bytecode/#4

      它解释了虽然在功能上是一致的(同步一个方法要么锁定实例对象,要么在静态方法的情况下锁定该方法所在类的 Class 对象),同步一个方法更优化,因为而不是在字节码中同步(就像同步块语句一样),它在 JVM 级别进行同步。

      【讨论】:

      • +1。最后是机制细节的提示和一个很好的链接(包括确切的问题)来支持它。
      【解决方案3】:

      一个区别是同步代码的粒度。在第一个示例中,您实际上锁定了整个方法,而在第二个示例中,只有方法的一部分将被锁定。对于不需要完全同步主体的长方法,第二种方法更好。最好只在需要时锁定并尽快为其他线程释放该锁定。

      【讨论】:

      • 但是,如果按照上面的例子,synchronized(this) 块包围了整个主体,该怎么办?字节码生成或监控对象有区别吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-12
      • 2011-01-09
      • 2012-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多