Java:除了它们所属的对象之外,同步方法还锁定什么(如果有的话)?
现在,我不确定这是否是一个愚蠢的问题,如果是,请耐心等待。
对象上的锁是否“递归”,即,如果两个对象在其字段中引用了第三个对象,并且一个线程正在这两个对象之一上运行同步方法,则任何其他线程都可以访问第三个对象吗?
// a and b are some objects that implement Runnable
// they both reference the same third object
a.ref = c;
b.ref = c;
// a is run in a thread and processes some data in a loop for a long time
// the method the loop belongs to is declared synchronized
threadA = new Thread(a);
threadA.start();
a.someSyncedMethod(); // this would block ...
b.ref.someOtherSyncedMethod(); // ... but would this?
a.ref.someOtherSyncedMethod(); // ... and how about this?
Now, I'm not sure whether this is a stupid question, please bear with me if it is.
Is the lock on an object "recursive", i. e. if two objects have references to a third object in their fields and a thread is running a synchronized method on one of the two, can any other thread access the third object?
// a and b are some objects that implement Runnable
// they both reference the same third object
a.ref = c;
b.ref = c;
// a is run in a thread and processes some data in a loop for a long time
// the method the loop belongs to is declared synchronized
threadA = new Thread(a);
threadA.start();
a.someSyncedMethod(); // this would block ...
b.ref.someOtherSyncedMethod(); // ... but would this?
a.ref.someOtherSyncedMethod(); // ... and how about this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
值得将“锁”和“锁定对象”的概念分开。 没有真正的“锁定对象”的想法 - 有“获取(和释放)”与对象关联的锁。 是的,这听起来像是我在吹毛求疵 - 但区别很重要,因为如果你谈论一个对象被锁定,那么听起来好像没有其他线程能够在该锁被锁定时更改该对象中的任何内容。握住。
相反,它仅意味着在持有锁时没有其他线程能够获取相同的锁。 锁与该锁关联的对象的任何内容之间没有直接关系。
声明为“同步”的方法获取与其所属对象的实例关联的锁。 这只会使同一对象上的其他同步方法等待,以及在该对象上显式同步的同步语句。
就我个人而言,我不喜欢同步方法 - 我喜欢通过显式同步仅用于同步的(私有、最终)成员变量来使其更清晰。
It's worth separating out the concepts of "a lock" and "locking an object". There's no real idea of "locking an object" - there's "acquiring (and releasing)" the lock associated with an object. Yes, it sounds like I'm nitpicking - but the distinction is important because if you talk about an object being locked it sounds like no other threads will be able to change anything in the object while that lock is held.
Instead, it just means that no other thread will be able to acquire the same lock while the lock is held. There's no direct relationship between the lock and any of the contents of the object that the lock is associated with.
Methods declared "synchronized" acquire the lock associated with the instance of the object they belong to. This only makes other synchronized methods on the same object wait, and synchronized statements that explicitly sync on it.
Personally I don't like synchronized methods - I like to make it clearer by explicitly synchronizing on a (private, final) member variable which is only used for synchronization.
仅当您将运行方法标记为同步或在同步方法中具有 ThreadA 运行代码时。
在 JVM 中,每个对象都拥有所谓的监视器。 一次只有一个线程可以拥有与给定对象关联的监视器。 同步是告诉当前线程在继续之前获取监视器的方法。
该类本身也拥有静态方法的监视器。
Only if you mark either the run method with synchronized or have ThreadA run code in synchronized methods.
In the JVM, each object owns what's known as a monitor. Only one thread can own the monitor associated with a given object at a time. Synchronized is the means by which you tell the current thread to go get the monitor before continuing.
Also the class itself owns a monitor for static methods.
“锁”(实际上这个变体称为监视器)的含义完全是一种约定,不强制执行访问限制。
该功能依赖于所有对象都表现良好并在访问数据之前获取相应的锁。 只有通过将这种所需的行为封装在具有适当访问控制的类中,您才能对客户端对象强制执行它。
The meaning of a "lock" (actually this variant is called a monitor) is entirely a convention, no access restrictions are enforced.
The functioning relies on all objects being well-behaved and acquiring the corresponding lock before accessing the data. Only by encapsulating this desired behaviour within in a class with proper access controls you can enforce it for the client objects.