Java synchronized lock key 对于同一对象的所有同步方法是否相同?

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

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

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

来自我最喜欢的关于 Java、Head First Java

的书

Every object has a lock. Most of the time, the lock is unlocked, and you can imagine a virtual key sitting with it. Object locks come into play only when there are synchronized methods.

When an object has one or more synchronized methods, a thread can enter a synchronized method only if the thread can get the key to the object’s lock!

The locks are not per method, they are per object.
If an object has two synchronized methods, it does not simply mean that you can’t have two threads entering the same method. It means you can’t have two threads entering any of the synchronized methods.

Think about it. If you have multiple methods that can potentially act on an object’s instance variables, all those methods need to be protected with synchronized.
The goal of synchronization is to protect critical data. But remember, you don’t lock the data itself, you synchronize the methods that access that data.

So what happens when a thread is cranking through its call stack (starting with the run() method) and it suddenly hits a synchronized method?
The thread recognizes that it needs a key for that object before it can enter the method. 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.
From that point forward, the thread hangs on to that key like the thread’s life depends on it. The thread won’t give up the key until it completes the synchronized method.
So while that thread is holding the key, no other threads can enter any of that object’s synchronized methods, because the one key for that object won’t be available.



长话短说:

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

为了补充上面发布的答案,我会尽力解释:

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

  • 对于静态方法,锁定在 class 级别。因此,无论 class 有多少个不同的实例,一次只能有一个线程访问一个方法。如果来自 class 的一个实例的第一个线程在其中一个 syncd 方法中,则另一个线程在同一个 class 和 same/different 实例 [=28] 中访问相同的不同 syncd 方法=] 必须等到第一个线程在 class 级别释放锁。

  • 对于 non-static 方法,锁定在 instance/object 级别。这意味着来自此 class 的 2 个不同实例的 2 个线程可以同时访问同一方法,因为锁对象是此 class.

    的 2 个不同实例