同一对象的所有同步方法的Java同步锁密钥是否相同?

同一对象的所有同步方法的Java同步锁密钥是否相同?,java,concurrency,synchronized,Java,Concurrency,Synchronized,如果我有两个或两个以上的同步方法,那么锁定键对于所有同步方法都是相同的?换句话说,如果一个线程处于同步方法中,那么如果任何其他线程想要访问某个其他同步方法,那么即使方法不同,也必须等待第一个线程结束?是的,您是对的。 要获得更详细的答案,请继续阅读。 从我最喜欢的关于Java的书中 每个对象都有一个锁。大多数情况下,锁是解锁的,并且 你可以想象一把虚拟钥匙坐在它旁边。对象锁进入 仅当存在同步方法时播放当 对象有一个或多个同步方法,线程可以输入 仅当线程可以获取对象的 锁 锁不是每个方法,而是每

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

是的,您是对的。 要获得更详细的答案,请继续阅读。

从我最喜欢的关于Java的书中

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

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

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

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

那又怎样 当线程通过其调用堆栈(启动)时发生 使用run()方法),它会突然遇到一个同步的方法?
线程认识到它需要该对象的键才能执行 它可以输入方法。它寻找钥匙(这一切都由 JVM;Java中没有用于访问对象锁的API),如果 密钥可用,线程抓取密钥并进入方法。
从那时起,线程像 线程的生命取决于它。线不会放弃的关键,直到它 完成同步方法。
因此,当线程保持 键,没有其他线程可以进入该对象的任何已同步线程 方法,因为该对象的一个键不可用



TL;博士:

每个Java对象都有一个锁。
也就是说,锁不是每个方法,而是每个对象。
现在,锁只有一把钥匙。
大多数时候,锁是锁 解锁,没人在乎。 但是如果一个物体
synchronized
方法,a 线程可以进入
synchronized
仅限方法 如果对象锁的钥匙 有空。换句话说,, 除非另一个线程没有
已经抓住了一键(通过输入
同步功能)。

要添加到上面发布的答案中,我将尽力解释:

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

  • 对于静态方法,锁位于类级别。因此,无论您有多少个不同的类实例,一次只能有一个线程访问一个方法。如果类的一个实例中的第一个线程位于其中一个syncd方法中,那么另一个线程访问同一个类中具有相同/不同类实例的不同syncd方法的相同线程将不得不等待,直到第一个线程在类级别释放锁

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


是的,只要你在同一个对象上同步那么多相似的问题,即使是SO自己的搜索也能找到其中两个问题,并将它们放在“相关”侧栏中。只是一个提示:不要考虑同步方法。方法不需要保护。需要保护的是方法操作所依据的数据。如果您有两个或多个方法可以从不同的线程调用以对相同的数据进行操作,那么这些方法绝对应该锁定相同的锁。