.class的Java同步块

时间:2010-01-13 11:33:48

标签: 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 ??
}

4 个答案:

答案 0 :(得分:134)

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

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

synchronized(X.class)用于确保块中只有一个Thread。 synchronized(this)确保每个实例只有一个线程。如果这使得块中线程安全的实际代码取决于实现。如果只改变实例synchronized(this)的状态就足够了。

答案 1 :(得分:75)

要添加其他答案:

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

相当于

static synchronized void myMethod() {
  //code
}

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

相当于

synchronized void myMethod() {
  //code
}

答案 2 :(得分:21)

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

第二个只会锁定当前实例。

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

答案 3 :(得分:0)

是的(在任何同步块/功能上)。

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

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

应始终进行类级别锁定,以确保静态数据线程安全。我们知道static关键字将方法的数据关联到类级别,因此请使用锁定静态字段或方法的方法将其设置为类级别。

加上注意为什么 .class 。仅仅是因为.class等于类的任何静态变量,类似于:

private final static Object lock = new Object();

其中锁定变量名称为 class ,类型为 Class

了解更多: https://howtodoinjava.com/java/multi-threading/object-vs-class-level-locking/