Java中类锁定和对象锁定的区别

xpl*_*raj 7 java multithreading locking thread-synchronization

人们讲述了两种类型的多线程锁定 - 对象和类.据我所知,锁定仅在对象上完成.

案例1:我们使用的工具new或工厂方法等.

void synchronized myMethod(Type param) {
  //will lock on the instance used to call this method
}
Run Code Online (Sandbox Code Playgroud)

要么

synchronized(this) {
 //will lock on current object
}
Run Code Online (Sandbox Code Playgroud)

要么

synchronized(obj1) {
 //will lock on specified obj1 object
}
Run Code Online (Sandbox Code Playgroud)

案例2:java.lang.Class对象

这称为类锁,可以与静态字段或方法或块一起使用,因为它们属于类并在所有对象和其他类属性之间共享.

static void synchronized method() {
  //will lock the Class object
}
Run Code Online (Sandbox Code Playgroud)

要么

static {
  synchronized(SomeClass.class){
    int a = 2;
  }
}
Run Code Online (Sandbox Code Playgroud)
  • 为什么我还将此视为对象锁定,因为类被加载到JVM中的方法区域中,并且类的所有静态属性都包装在java.lang.Class由JVM创建的对象中.因此抽象,它的对象锁定和图片中,我们看到类锁定.
  • 所以我还可以推断出一件事.正如一个线程锁定的对象不能被另一个线程获取,只要它不被第一个线程释放,类锁定(java.lang.Class实例)也以相同的方式工作.
  • 我想知道在同步静态方法的情况下,在以下两种情况下锁定线程获取哪个类:

    1. 从定义它的同一个类调用此方法.
    2. 从具有派生类名的派生类调用此方法.

到目前为止,这是我对这个问题的理解.请加上或纠正.

Sol*_*low 9

人们讲述了两种类型的多线程锁定 - 对象和类.

一个对象.Java 语言中只有一种锁定:每个对象(包括每个类)都有一个可以被synchronized块或synchronized方法锁定的互斥锁.要锁定的Object隐含在synchronized方法中:它是实例方法的"this"实例,它是静态方法的Class对象.

最常见的新手错误之一是认为两个不同的线程无法同时进入同一个synchronized块.他们可以,并且StackOverflow中有很多问题和答案可以证明这一点.另一个错误是认为如果一个线程在某个对象上同步,那么其他线程将无法修改该对象.他们可以和他们一样.

同步可防止两个或多个线程同时在同一个Object上进行同步.哪个对象是正确的对象?这一切都与保护您的数据有关.例如,如果要保护的结构是链接列表,则可以选择访问列表以在列表标题上进行同步的任何方法.如果要保护全局数据(例如,static变量),则需要在全局对象上进行同步(例如,拥有变量的Class对象.)重要的是,如果您有读/写数据(也就是说, "可变数据")由多个线程访问,然后访问相同数据的每个方法必须在同一个锁上同步.


Java中有另一种锁定,但它不是Java 语言 ; 它在Java标准库中.它可以通过实现java.util.concurrent.locks.Lock接口的对象获得.当然,一个锁定对象(像任何对象)也实现了第一类锁定的,但你应该永远,永远,一个锁对象上,除非你想给人们的印象是,你是一个无能的新手同步.

java.util.concurrent样式的锁定比使用synchronized块更强大,因为它是显式的lock()和unlock()方法.例如,一种方法可以锁定锁,而另一种方法可以解锁.这可能导致代码难以理解,除非我有充分的理由,否则我不会这样做,但有时候有充分的理由.

  • @HarishAmarnath,对象是_never_无法修改.`synchronized(foo)`块不会阻止其他线程修改`foo`:它只会阻止其他线程进入`synchronized(foo)`块. (3认同)

Pet*_*rey 4

唯一的区别是类实例上的锁和实例上的static synchronized非静态方法锁。synchronized

人们讲述了两种类型的多线程锁定

有对象实例锁和Lock样式锁。Lock令人困惑的是,A两者都有。

对象和类

不正确,因为您已经解决了。

仅仅因为人们说了一些话并不意味着它就是真的。很多时候人们会说很多废话。事实上,有很多网站专门讨论有关 Java 的废话。:P

  • @xploreraj 正确。您可以使用 A.add() *和* B.add(),两者都是静态的和同步的。如果 B.add() 调用 A.add() 并且您调用 B.add(),则 B.class 和 A.class 都会被锁定。 (2认同)