Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中类锁定和对象锁定的区别_Java_Multithreading_Locking_Thread Synchronization - Fatal编程技术网

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

Java中类锁定和对象锁定的区别,java,multithreading,locking,thread-synchronization,Java,Multithreading,Locking,Thread Synchronization,人们讲述了两种类型的多线程锁定-对象和类。据我所知,锁定只在对象上完成 案例1:在对象上,我们使用new或工厂方法等创建 void synchronized myMethod(Type param) { //will lock on the instance used to call this method } 或 或 案例2:Onjava.lang.Classobjects 这称为类锁,可用于静态字段、方法或块,因为它们属于类并在所有对象和其他类属性之间共享 static void sy

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

案例1:在对象上,我们使用
new
或工厂方法等创建

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

案例2:On
java.lang.Class
objects

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

static void synchronized method() {
  //will lock the Class object
}

  • 为什么我认为这也是一个对象锁定,因为类被加载到JVM的方法区域中,并且类的所有静态属性都被包装在JVM创建的
    java.lang.class
    对象中。所以在抽象的背后,它的对象锁定,在图中,我们看到了类锁定
  • 所以我还可以推断出一件事。正如一个线程锁定的对象不能被另一个线程获取,只要它不是由第一个线程释放的,类锁定(java.lang.class实例)也以同样的方式工作
  • 我想知道在同步静态方法的情况下,在以下两种情况下锁定线程获取的类:

  • 此方法是从定义它的同一个类调用的
  • 此方法是从具有派生类名的派生类调用的

这是我到目前为止对这个问题的理解。请添加或更正。

唯一的区别是
静态同步的
锁定类实例,而非静态的
同步的
方法锁定实例

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

有对象实例锁和
样式锁。令人困惑的是,
锁同时具有这两种功能

对象和类

不是真的,你已经知道了

只是因为人们说的东西不能使它成为现实。人们经常说很多废话。事实上,整个网站都致力于对Java毫无意义的研究P

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

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


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

同步防止两个或多个线程同时在同一对象上同步。哪个对象是正确的对象?这一切都是为了保护您的数据。例如,如果要保护的结构是一个链表,那么访问该列表的任何方法都可以在列表头上进行同步,这是一个很好的选择。如果要保护全局数据(例如,
静态
变量),则需要在全局对象(例如,拥有变量的类对象)上进行同步。重要的是,如果有多个线程访问的读/写数据(也称为“可变数据”),然后,访问相同数据的每个方法必须在同一个锁上同步


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


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

考虑两类:
类a
类B扩展了a
。方法具有静态同步int add()
。现在从B类开始,如果我调用
B.add()
,它将正确锁定B类对象,如果我调用
A.add()
,它将正确锁定一个类对象?当B类对象被锁定时,另一个线程不能修改其他B静态字段或方法等。,。如果它们是同步的。如果不同步,可以由任意数量的线程同时修改吗?@xploreraj没有B.add(),只有A.add(),因此A.class将被锁定。您可以调用new B().add(),但它仍将锁定A.class。当您锁定B.class时,另一个线程无法锁定B.class,但它可以访问它可以访问的任何其他内容,例如方法和字段。如果未同步或
Lock
ed,则对多个线程执行多次写入/读取没有限制。您可以调用新的
new B().add()
,但它仍将锁定A.class
add()
是基类中的静态方法,所以我可以直接执行
B.add()
。它锁定
A.class
,因为该方法位于A中,与调用方无关。如果在相同的情况下,在B类中也定义了
add()
,那么它将锁定
B.class
。纠正我!谢谢彼得:)@xploreraj正确。可以有A.add()和B.add(),它们都是静态的和同步的。如果B.add()调用A.add()并
synchronized(obj1) {
 //will lock on specified obj1 object
}
static void synchronized method() {
  //will lock the Class object
}
static {
  synchronized(SomeClass.class){
    int a = 2;
  }
}