Java 什么是类级、对象级、显式和内在锁定?

Java 什么是类级、对象级、显式和内在锁定?,java,multithreading,locking,Java,Multithreading,Locking,我一直在学习Java多线程的概念。我看得越多,就越糊涂 现在我还不了解Java中类级、对象级、显式和内在锁定之间的区别。有人能告诉我哪个是什么吗?另外,如果我能理解一些例子,那将对我非常有帮助。显式与内在 当您在对象上使用synchronized或间接作为方法签名的一部分时,您正在创建一个。您依赖于与所有对象和类关联的内置锁 Java5+在包Java.util.concurrent.locks中提供了一个显式锁。最常用的类可能是ReentrantLock。它们提供了使用内在锁的替代方案,并提供了

我一直在学习Java多线程的概念。我看得越多,就越糊涂

现在我还不了解Java中类级、对象级、显式和内在锁定之间的区别。有人能告诉我哪个是什么吗?另外,如果我能理解一些例子,那将对我非常有帮助。

显式与内在 当您在对象上使用
synchronized
或间接作为方法签名的一部分时,您正在创建一个。您依赖于与所有对象和类关联的内置锁

Java5+在包
Java.util.concurrent.locks
中提供了一个显式锁。最常用的类可能是
ReentrantLock
。它们提供了使用内在锁的替代方案,并提供了内在锁无法实现的功能

类级别与对象级别 这种区别仅适用于内部锁。如果有,则使用的内部锁将与类对象本身相关联。如果在对象实例上同步(或具有同步实例方法),则它将是对象级锁


进一步阅读 Brian Goetz的书是一本很好的书,它帮助我们理解了Java中多线程编程的噩梦般的混乱世界。

“类级”锁定和“对象级”锁定都是人为的想法,作者可能对Java的内在锁定的工作原理没有深入的了解

类级锁定如下所示:

class Foobar {
    static synchronized void moo() { ... }
}
class Foobar {
    synchronized void baa() { ... }
}
但这种结构实际上只是一种简写方式:

class Foobar {
    static void moo() {
        synchronized (Foobar.class) { ... }
    }
}
和对象级锁定,如下所示:

class Foobar {
    static synchronized void moo() { ... }
}
class Foobar {
    synchronized void baa() { ... }
}
只不过是以下方面的简写:

class Foobar {
    static void baa() {
        synchronized (this) { ... }
    }
}
因此,实际上,在“类级”和“对象级”锁定下面,只有一个概念,
synchronized
块:

synchronized(objectReference) {...}
您需要知道的是,JVM将不允许多个线程同时在同一对象上同步

如果要保护的数据是全局数据,那么在访问数据时在全局单例对象上同步是有意义的
Foobar.class
是一个全局单例

当要保护的数据完全包含在某个对象实例中时,在与该实例关联的某个对象上或在实例本身(即,
)上进行同步是有意义的。

当使用“Synchronized”关键字时,它使用内部锁或监视器。Java中的每个对象都有一个与之关联的内在锁。每当线程试图访问同步块或方法时,它就会获取该对象或对象级锁上的内部锁或监视器。对于静态方法,线程获取类对象上的

public synchronized void doAtomicTransfer(){
  //enter synchronized block , acquire lock over this object.
  operation1()
  operation2();   
} // exiting synchronized block, release lock over this object.
固有锁定机制可能有一些功能限制,例如:

  • 不可能中断等待获取锁的线程(可中断地锁定)
  • 如果不愿意永远等待锁,就不可能尝试获取锁(try lock)。一次只能有一个线程持有锁:例如,没有允许多个线程同时持有锁以进行只读访问的工具
  • 无法实现非块结构化锁定规程,因为必须在获取内部锁的同一块中释放内部锁
在需要克服内置同步的某些缺点的情况下非常有用。特别是,它们具有以下特点:

  • 线程可以尝试中断地获取锁
  • 线程可以为尝试获取锁提供超时值
  • 支持读/写锁–即,如果锁未锁定用于写入,则允许多个并发读卡器的锁
  • 传统的等待/通知隐喻被扩展为允许条件(见下文)
  • 对公平性的支持(如果有多个线程在等待一个锁,那么当锁可用时,它们将以先进先出的顺序获取)
  • 锁定块范围之外的能力:例如,一个方法可以将锁定对象传递给另一个线程
  • 例如,可以查询锁以确定它们当前是否有任何线程等待获取它们

您将在哪里查看它们?有什么特别的书吗?希望这有点帮助@BartlomiejLewandowski:没有,我在看各种互联网资源,他们把我搞糊涂了。我重新打开了这个。出于某种原因,它被关闭为@AmanArora链接到的问题的副本。然而,这两个问题是完全不同的。是的,链接到的答案提供了这个问题的一些答案,但这并不意味着它是一个重复。因此,这意味着,类级和对象级锁定实际上只是内在锁的子类型,但显式锁/重入锁是一个完全不同的东西?@thedarknight是的。但更让人困惑的是,内在锁也是可重入的(即持有锁的人可以再次获得它)。哦……你在杀我:)好吧,这就解决了大部分问题。你能告诉我显式锁的代码吗?谢谢你提供的信息。这真让我头疼。@DarkKnight在
ReentrantLock
Javadocs类中有一些简单的代码示例。否则我肯定谷歌是你的朋友。谢谢,这是很有见地的。