【问题标题】:Difference: this vs Myclass.class vs MyClass.getClass() in synchronisation [duplicate]区别:同步中的 this vs Myclass.class vs MyClass.getClass() [重复]
【发布时间】:2018-08-14 10:32:04
【问题描述】:

我正在尝试使用以下方法了解同步的确切差异:

  1. synchronized(MyClass.class){...}

  2. synchronized(myClassInstance.getClass()){...} [编辑为MyClass.getClass() 甚至无法编译]

  3. synchronized(this){...}

感谢其他帖子,我知道 (1) 用于确保块中只有一个线程,而 (3) 确保每个实例只有一个线程

(见Java Synchronized Block for .class

但是 (2) 做了什么?是否与(3)相同?

【问题讨论】:

  • (1) 在Class 上同步,(2) 不编译:您在静态上下文中使用实例方法,(3) 在实例上同步。
  • 如果你写myClassInstance#2 会起作用,但在这种情况下,它与#1 相同;该类的引用方式不同(也就是说,如果myClassInstance 不是派生类的实例而不是基类)。
  • #2 至少也可以用MyClass.class.getClass() 编译,不是吗?
  • @Clijsters 不,那将是类实例的类,对于任何类可能都是相同的(当然是class java.lang.Class)。好吧,它会起作用:它会以与我假设的 #1 相同的方式锁定,但不建议对非本地的东西设置锁定。
  • 我刚做了它并编译了。当您编辑您的评论时:我只是说它会编译,这没有意义,也不推荐;)

标签: java multithreading synchronization thread-safety


【解决方案1】:

您提到您已经了解选项 #1 和 #3,所以我将专注于选项 #2。

正如我在问题 cmets 中所述,选项 #2 不会按书面方式编译。但是,我相信您的意图是以实例方式而不是静态方式获取类 (MyClass.class)。

public class MyClass {

    public void foo() {
        synchronized (MyClass.class) {
        }
    }

    public void bar() {
        synchronized (getClass()) {
        }
    }

}

在上面的代码中,MyClass.classgetClass() 都返回 same 对象,这意味着它们是“等价的”。但是,您必须在这里小心。

public class MySubClass extends MyClass {
    // inherits methods...
}

现在这两种方法(foobar)是等效的。方法foo 仍然使用MyClassClass 进行同步,但bar 现在使用MySubClassClass(即它们不再在同一个对象上同步)。

【讨论】:

    【解决方案2】:

    第 1 点将锁定 Class Object 并且在 JVM 中只能存在一个对象(如果同一个类没有被不同的类加载器加载)。这可以与静态以及中午静态方法一起使用

    第二个选项不会编译。

    第三个选项将锁定当前对象。第三个选项可以与实例方法一起使用,因为这可以用于静态方法的情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-13
      • 1970-01-01
      • 2014-05-20
      • 2012-09-24
      • 1970-01-01
      • 2016-05-16
      相关资源
      最近更新 更多