对于同一对象的所有同步方法,Java 同步锁键是否相同?



如果我有两个或多个同步方法,那么所有同步方法的锁定键都相同吗?换句话说,如果一个线程在同步方法中,那么如果任何其他线程想要访问其他一些同步方法,那么即使方法不同,也必须等待第一个线程结束?

是的,你是对的。 有关更详细的答案,请继续阅读。

出自我最喜欢的关于Java的书,Head First Java

每个对象都有一个锁。大多数时候,锁是解锁的,并且 你可以想象一个虚拟钥匙坐在它旁边。对象锁进入 仅在有同步方法时播放。

当一个 对象有一个或多个同步方法,一个线程可以输入 仅当线程可以获取对象的键时,才同步方法 锁!

锁不是按方法,而是按对象。
如果一个对象有两个同步的方法,这不仅仅意味着你 不能有两个线程进入相同的方法。这意味着你不能 有两个线程进入任何同步方法。

想想吧。如果您有多种可能起作用的方法 在对象的实例变量上,所有这些方法都需要 受同步保护。
同步的目标是 保护关键数据。但请记住,您不会锁定数据本身, 同步访问该数据的方法。

那又怎样 当线程通过其调用堆栈(启动 使用 run(( 方法(,它突然命中同步方法?
线程识别出它需要该对象的键之前 它可以输入方法。它查找密钥(这全部由 JVM;Java 中没有用于访问对象锁的 API(,如果 密钥可用,线程获取密钥并输入方法。
从那时起,线程将挂在该键上,例如 线程的生命取决于它。线程不会放弃密钥,直到它 完成同步方法。
所以当线程保持时 键,没有其他线程可以进入该对象的任何同步 方法,因为该对象的 One 键将不可用。



TL;博士:

每个 Java 对象都有一个锁。
也就是说,锁不是按方法,而是按对象。
现在,一把锁只有一个钥匙。
大多数时候,锁是 解锁,没人在乎。 但是如果一个对象有synchronized方法,a 线程可以输入其中之一 仅synchronized方法 如果对象锁的密钥可用。换句话说, 仅当另一个线程没有 已经抓住了一个键(通过输入synchronized功能(。

为了补充上面发布的答案,我将尽我所知尝试解释:

类中的同步方法可以是静态的,也可以是非静态的

  • 对于静态方法,锁位于类级别。因此,无论您有多少个不同的类实例,一次只有一个线程可以访问一个方法。如果来自类的一个实例的第一个线程位于其中一个同步方法中,则访问同一类中具有相同/不同类实例的不同同步方法的另一个线程必须等到第一个线程在类级别释放锁。

  • 对于非静态方法,锁位于实例/对象级别。这意味着来自此类的 2 个独立实例的 2 个线程可以同时访问同一方法,因为 lock 对象是此类的 2 个不同实例。

最新更新