.class的Java同步块

.class的Java同步块,java,multithreading,synchronization,locking,synchronized,Java,Multithreading,Synchronization,Locking,Synchronized,这段java代码是什么意思?它会锁定MyClass的所有对象吗 synchronized(MyClass.class) { //is all objects of MyClass are thread-safe now ?? } 以及上述代码与此代码的区别: synchronized(this) { //is all objects of MyClass are thread-safe now ?? } 不,第一个将锁定MyClass的类定义,而不是它的所有实例。但是,如果在实例

这段java代码是什么意思?它会锁定
MyClass
的所有对象吗

synchronized(MyClass.class) {
   //is all objects of MyClass are thread-safe now ??
}
以及上述代码与此代码的区别:

synchronized(this) {
   //is all objects of MyClass are thread-safe now ??
}

不,第一个将锁定
MyClass
的类定义,而不是它的所有实例。但是,如果在实例中使用,这将有效地阻止所有其他实例,因为它们共享一个类定义

第二个将只获得当前实例的锁


至于这是否使您的对象线程安全,这是一个更复杂的问题-我们需要查看您的代码

代码片段
synchronized(X.class)
将类实例用作监视器。由于只有一个类实例(运行时表示类元数据的对象),因此该块中可以有一个线程

使用
synchronized(this)
该块由实例保护。对于每个实例,只有一个线程可以进入块


synchronized(X.class)
用于确保块中只有一个线程
synchronized(这)
确保每个实例只有一个线程。这是否使块中的实际代码线程安全取决于实现。如果仅对已同步实例的状态进行变异(此)就足够了。

要添加到其他答案中:

static void myMethod() {
  synchronized(MyClass.class) {
    //code
  }
}
相当于

static synchronized void myMethod() {
  //code
}
synchronized void myMethod() {
  //code
}

相当于

static synchronized void myMethod() {
  //code
}
synchronized void myMethod() {
  //code
}
是(在任何同步块/功能上)

我为自己(实际上是在科特林)想了几天这个问题。我终于找到了很好的解释,并想与大家分享:

类级锁防止多个线程在运行时进入类的任何可用实例中的同步块。这意味着,如果在运行时有100个DemoClass实例,那么一次只有一个线程能够在任何一个实例中执行demoMethod(),所有其他实例都将被其他线程锁定。

应始终执行类级锁定,以使静态数据线程安全。正如我们所知,static关键字将方法的数据关联到类级别,所以在静态字段或方法上使用锁定使其在类级别上

另外请注意为什么.class。这只是因为
.class
等价于类的任何静态变量,类似于:

private final static Object lock = new Object();
其中锁变量名为class,类型为class

阅读更多:

是的,MyClass.class可以是任何静态变量,并且具有相同的效果。“有实例的线程可能会进入块”,这意味着第二种形式充当了一个信号量,这是不正确的。您应该这样说:“synchronized(this)确保只有一个线程可以进入类的给定实例的块”。更正。我想说的是,类实例和实例是什么?所以,如果你有一个静态方法,我们不想同步它的所有主体,那么我们同步(这)是不好的,而同步(Foo.class)是合适的。是这样吗?相关:我花了二读才明白前两个例子的关键字是“static”。只是向其他人指出这一点,他们可能已经看到并错过了这一点。如果没有static关键字,前两个例子就不一样了。这些例子是不等价的!当线程尝试调用同步方法时,同步方法被“同步”为孔。另一方面,块上下都可以有代码,可以从多个线程执行。它们只在块内同步!那不一样!公共静态单例getInstance(){if(instance==null){synchronized(Singleton.class){instance=new Singleton();}}}返回instance;}关键是在
synchronized
块之外没有代码。这使得它们相当。如果你改变一个例子,它们确实不再相同了。