代码之家  ›  专栏  ›  技术社区  ›  James McMahon

Java:什么东西,如果有的话,除了它们所属的对象之外,被同步方法锁定了吗?

  •  5
  • James McMahon  · 技术社区  · 16 年前

    现在,我不确定这是不是一个愚蠢的问题,如果是,请跟我说。

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

    // 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 回复  |  直到 16 年前
        1
  •  10
  •   Jon Skeet    16 年前

    有必要将“锁”和“锁定对象”的概念分开。没有“锁定对象”的真正概念——有“获取(和释放)”锁 关联 物体。是的,听起来我在吹毛求疵-但是区别很重要,因为如果你说 对象 被锁定时,听起来没有其他线程能够在锁定期间更改对象中的任何内容。

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

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

    就我个人而言,我不喜欢同步方法——我喜欢通过在只用于同步的(private,final)成员变量上显式同步使其更清晰。

        2
  •  1
  •   Martin OConnor    16 年前
    a.someSyncedMethod(); // this would block ...
    

    只有当您将run方法标记为synchronized或将threada运行代码标记为synchronized方法时。

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

    此外,类本身还拥有静态方法的监视器。

        3
  •  0
  •   starblue    16 年前

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

    功能依赖于所有对象行为良好,并在访问数据之前获取相应的锁。只有在具有适当访问控制的类中封装这种所需的行为,您才能为客户机对象强制实施它。