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? 

值得分离出“锁定”和“锁定对象”的概念。 没有关于“锁定对象”的真实想法 – “获取(和释放)” 对象关联的锁。 是的,这听起来像是在挑剔 – 但区别很重要,因为如果你谈论被锁定的对象 ,听起来没有其他线程能够在保持锁定时改变对象中的任何东西。

相反,它只是意味着在锁定时没有其他线程能够获得相同的锁。 锁与锁定关联的对象的任何内容之间没有直接关系。

声明为“synchronized”的方法获取与其所属对象的实例关联的锁。 这只会使同一对象上的其他同步方法等待,并在其上显式同步同步语句。

我个人不喜欢同步方法 – 我喜欢通过显式同步一个仅用于同步的(私有的,最终的)成员变量来使它更清晰。

 a.someSyncedMethod(); // this would block ... 

仅当您使用synchronized标记run方法或在同步方法中使用ThreadA运行代码时。

在JVM中,每个对象都拥有所谓的监视器。 一次只有一个线程可以拥有与给定对象关联的监视器。 Synchronized是在继续之前告诉当前线程获取监视器的方法。

该类本身也拥有静态方法的监视器。

“锁定”(实际上这种变体称为监视器)的含义完全是一种约定,不强制执行访问限制。

function依赖于所有对象都表现良好并在访问数据之前获取相应的锁。 只有通过在具有适当访问控制的类中封装此所需行为,您才能对客户端对象强制执行该行为。