Java中类锁和对象锁的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23261120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 21:33:32  来源:igfitidea点击:

Difference between class locking and object locking in Java

javamultithreadinglockingthread-synchronization

提问by xploreraj

People tell about two types of multi-threaded locking - object and class. In my knowledge, locking is done on objects only.

人们讲述了两种类型的多线程锁定 - 对象和类。据我所知,锁定仅对对象进行。

Case 1: On objects we createusing newor factory methods etc.

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

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

or

或者

synchronized(this) {
 //will lock on current object
}

or

或者

synchronized(obj1) {
 //will lock on specified obj1 object
}

Case 2: On java.lang.Classobjects

案例 2:在java.lang.Class对象上

This is called class lock, and can be used with static fields or methods or blocks, as they belong to class and shared among all the objects, and other class properties.

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

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

or

或者

static {
  synchronized(SomeClass.class){
    int a = 2;
  }
}
  • Why I am thinking this also as an object locking because classes are loaded into the Method Area in the JVM, and all the static properties of the class are wrapped inside a java.lang.Classobject created by JVM. So behind abstraction, its object locking and in the picture, we see Class locking.
  • So I can also infer one more thing. Just as objects locked by a thread can not be acquired by another thread as long as it is not released by first thread, class locking (the java.lang.Classinstance) also works in same manner.
  • I want to know in case of synchronized static methods, lock on which class is acquired by the thread in following two cases:

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

    1. 这个方法是从定义它的同一个类调用的。
    2. 这个方法是从派生类调用的,派生类名。

This is my understanding so far regarding the subject. Please add on or rectify.

到目前为止,这是我对这个主题的理解。请补充或纠正。

采纳答案by Peter Lawrey

The only difference is that a static synchronizedlocks on the class instance and a non-static synchronizedmethod locks on the instance.

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

People tell about two types of multi-threaded locking

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

There is object instance locks and Lockstyle locks. A Lock, confusingly, has both.

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

object and class

对象和类

Not true as you have worked out already.

不是真的,因为你已经解决了。

Just because people say stuff doesn't make it true. Often people say a lot of nonsense. In fact there is whole web sites devoted to non-sense about Java. :P

仅仅因为人们说的东西并不能使它成为真的。经常有人说很多废话。事实上,有很多网站专门讨论关于 Java 的废话。:P

回答by Solomon Slow

People tell about two types of multi-threaded locking - object and class.

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

A Class isan Object. There is only one kind of locking in the Java language: Every Object (including every Class) has a mutex that can be locked by a synchronizedblock or a synchronizedmethod. The Object to be locked is implicit in a synchronizedmethod: It's the "this" instance for an instance method, and it's the Class object for a static method.

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

One of the most common newbie mistakes is to think that two different threads can't get into the same synchronizedblock at the same time. They can, and there's plenty of questions and answers here in StackOverflow that prove it. Another mistake is to think that if one thread is synchronized on some object, then other threads will not be able to modify the object. They canand they do.

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

Synchronization prevents two or more threads from synchronizing on the same Objectat the same time. Which object is the right object? It's all about protecting your data. If the structure that you want to protect is a linked list, for example, then a good choice would be for any method that accesses the list to synchronize on the list header. If you want to protect global data (e.g., staticvariables), then you want to synchronize on a global object (e.g., the Class object that owns the variables.) The important thing is that, if you have read/write data (a.k.a., "mutable data") that are accessed by more than one thread, then everymethod that accesses the same data must synchronize on the samelock.

同步防止两个或多个线程同时在同一个对象上同步。哪个对象是正确的对象?这一切都是为了保护您的数据。例如,如果您要保护的结构是链表,那么对于访问列表的任何方法在列表头上进行同步都是一个不错的选择。如果您想保护全局数据(例如,static变量),那么您希望在全局对象(例如,拥有变量的 Class 对象)上进行同步。重要的是,如果您有读/写数据(也就是, “可变数据”)被多个线程访问,那么访问相同数据的每个方法都必须在同一个锁上同步。



There is another kind of locking in Java, but it's not in the Java language; it's in the Java standard library. It's available through objects that implement the java.util.concurrent.locks.Lock interface. Of course a Lock object (like any Object) also implements the first kind of locking, but you should never, ever, synchronize on a Lock object unless you want to give people the impression that you are a clueless newbie.

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

The java.util.concurrent-style locking is more powerful than using synchronizedblocks because of it's explicit lock() and unlock() methods. For example, it is possible for one method to lock a lock, and a different method to unlock it. That can lead to code that is tricky to understand, and I wouldn't do it unless I had a very good reason, but sometimes there are good reasons.

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