Java:除了它们所属的对象之外,同步方法是否锁定了什么?

时间:2009-03-04 10:15:19

标签: java concurrency locking mutex semaphore

现在,我不确定这是否是一个愚蠢的问题,如果是的话,请耐心等待。

对象上的锁是“递归的”,i。即如果两个对象在其字段中引用了第三个对象,并且一个线程正在其中一个上运行同步方法,那么任何其他线程是否可以访问第三个对象?

// 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?

3 个答案:

答案 0 :(得分:10)

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

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

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

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

答案 1 :(得分:1)

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

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

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

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

答案 2 :(得分:0)

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

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