繁体   English   中英

对于同一 object 的所有同步方法,Java 同步锁定密钥是否相同?

[英]Is Java synchronized lock key the same for all synchronized methods of the same object?

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

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

来自我最喜欢的书 Java, Head First Java

每个object都有一把锁。 大多数时候,锁是解锁的,你可以想象一把虚拟钥匙和它坐在一起。 Object 锁只有在有同步方法时才起作用。

当一个 object 有一个或多个同步方法时,线程只有获得对象锁的密钥才能进入同步方法!

锁不是每个方法,它们是每个 object。
如果一个 object 有两个同步方法,这并不简单意味着你不能让两个线程进入同一个方法。 这意味着您不能让两个线程进入任何同步方法。

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

那么当一个线程在它的调用堆栈中运行(从 run() 方法开始)并且它突然遇到一个同步方法时会发生什么?
该线程识别出它需要该 object 的密钥才能进入该方法。 It looks for the key (this is all handled by the JVM; there's no API in Java for accessing object locks), and if the key is available, the thread grabs the key and enters the method.
从那时起,线程就挂在那个键上,就像线程的生命依赖于它一样。 线程在完成同步方法之前不会放弃密钥。
因此,当该线程持有密钥时,没有其他线程可以进入该对象的任何同步方法,因为该 object 的一个密钥将不可用。



TL;博士:

每个 Java object 都有一把锁。
也就是说,锁不是每个方法,而是每个 object。
现在,一把锁只有一把钥匙。
大多数时候,锁是解锁的,没有人在乎。 但是,如果 object 具有synchronized方法,则只有在对象锁的密钥可用时,线程才能进入synchronized方法之一。 换句话说,只有当另一个线程还没有抓住一个键(通过输入synchronized函数)。

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

class 中的同步方法可以是 static 或非静态的

  • 在 static 方法的情况下,锁定在 class 级别。 因此,无论您拥有多少个不同的 class 实例,一次只有一个线程可以访问一个方法。 如果 class 的一个实例的第一个线程在一个同步方法中,则另一个线程访问同一 class 中不同同步方法的相同/不同实例的 class 的相同/不同实例将等待第一个线程释放class 级。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM