【问题标题】:How is class level locking achieved in java?java中如何实现类级锁定?
【发布时间】:2014-06-05 19:30:33
【问题描述】:

我知道使用静态和非静态方法同步来分别锁定类和实例的锁定概念。我无法理解的是,类级锁是如何实现的?我的意思是,类只是一个模板,没有物理意义。那么,当我们说通过同步静态方法实现类级别锁定时,会发生什么?该类的所有对象是否都被锁定或其他进程?

我可以通过搜索发现有类对象(Class.class)并且在这个类对象上获得了锁。但是那个类的所有实例又是如何被锁定的呢?

【问题讨论】:

  • Class 类也得到一个 Class 对象。
  • class is a template only, with no physical significance。错误的。每个类在 JVM 中都有其 Class 对象。
  • 另外,你认为类的静态成员住在哪里?
  • 只需使用synchronized(ABC.class){...}
  • 类锁不会锁定所有实例。它提供了类级别的锁。假设您有一个静态集合来跟踪类的所有实例。在向其中添加或从中删除时,您可能希望锁定此集合。您可以在类或静态方法上同步,也可能在静态集合本身上同步。这只是意味着如果一个线程在同步块中,另一个线程将在尝试进入它时阻塞,直到第一个线程退出同步块。

标签: java multithreading synchronization locks


【解决方案1】:

该类的所有对象是否都被锁定或其他进程?

首先,我们来谈谈“锁定”一个对象是什么意思。

Foobar foobar = new Foobar();

synchronized (foobar) {
    ...
}

当线程位于synchronized 块中时,您可能会说 foobar 对象被“锁定”。但这对程序有什么作用?很多新手错误地认为它会阻止其他线程访问该对象。但是,这不是正确的。 synchronized 所做的——synchronized 唯一做的事情——是保证同一对象上不能同时同步多个线程。

上例中程序员的意图可能是防止其他线程看到 foobar 处于不一致状态。在这种情况下,访问 foobar 的每个方法和每个代码片段都必须在 foobar 上同步。将 foobar 想象成有许多门的大房间。使用 foobar 的每种方法都像是一扇不同的门。如果你想让人们离开房间,只锁一扇门是没有用的。您必须锁定所有个。

那么现在,回答你的问题:

当我们说通过同步静态方法实现类级别锁定时,会发生什么?

简单。这个:

class Foobar {
    static synchonized void do_something() {
        ...
    }
}

和这个完全一样:

class Foobar {
    static void do_something() {
        synchronized(Foobar.class) {
            ...
        }
    }
}

你总是在一个对象上同步。嗯,一个类一个对象。当static 方法为synchronized 时,仅表示方法体在类对象上同步。

由于一个类是一个单例对象,这意味着没有两个线程可以同时进入同一个静态同步方法。在我之前的示例中,变量 foobar 可以在不同的时间引用不同的对象,但在静态示例中,Foobar.class 保证始终引用同一个单例。


编辑:正如@Danny 指出的那样,在 Foobar 类(我的第二个示例)上同步的块与在 instance 的Foobar 类(我的第一个例子)。实例和类对象是两个不同的对象,所以没有什么能阻止一个线程在实例上同步而另一个线程在类上同步。同样,没有什么能阻止两个不同的线程在两个不同的实例上同步。新手经常犯的另一个错误是认为一次只有一个线程可以进入这个synchronized块:

Integer n = ...;

synchronized (n) {
    n = n+1;
    ...
}

但事实并非如此。锁定的不是变量 n,而是 Integer 类的特定实例。进入块的每个线程都会创建一个新的 Integer 实例并将其分配给 n。因此,当下一个线程出现时,n 不再指代第一个线程已同步的同一个实例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 2012-01-19
    • 2011-07-23
    • 1970-01-01
    相关资源
    最近更新 更多