我有一个作为 Spring 有线 bean 的经理。我相信默认情况下为 spring 定义的每个 bean 都连接为单例。我在这个 bean 中有一些需要同步的方法。那我该怎么做——
void zzz() {
synchronized (this) {
...
}
}
或者
void zzz() {
synchronized (MyClass.class) {
...
}
}
?
我有一个作为 Spring 有线 bean 的经理。我相信默认情况下为 spring 定义的每个 bean 都连接为单例。我在这个 bean 中有一些需要同步的方法。那我该怎么做——
void zzz() {
synchronized (this) {
...
}
}
或者
void zzz() {
synchronized (MyClass.class) {
...
}
}
?
两者的主要区别在于第一种情况下,类的实例作为监视器,而第二种使用类作为监视器。
第一个可能是您的情况,因为在不久的将来,如果您决定拥有许多类的实例,它们的方法将在各自的实例上同步。与将 Class 用作监视器相反,如果一个线程在一个实例上调用同步方法,则其他线程将无法在同一类的任何实例上调用方法(那些同步的方法)。
除非您正在访问可变的静态类变量(一开始可能很讨厌),否则第一个是同步的适当方式。
了解虽然 Spring 仅创建一个单例 bean 的实例并将其用于依赖于该类型 bean 的任何人,但单例不是静态实体。没有编译器约束阻止您在 Spring 上下文之外自己实例化该类。这只是唯一的例子,因为 Spring 知道不要制造更多……而不是因为它不能完成。我在这里要说明的一点是,在类级数据和单例数据之间进行平行是不正确的。
因此,同步应该发生在尽可能窄的范围内。在您的情况下,这意味着在包含共享数据的对象实例上同步,而不是在整个类的更广泛范围上同步。