Class
和instance
同步是有区别的。
实例同步适用于 的每个实例Object
,因此代码:
public synchronized void putInCache() {
// ... do some stuff
cache.insert(this);
// ... do some more stuff
}
和代码
public void putInCache() {
synchronized(this) {
// ... do some stuff
cache.insert(this);
// ... do some more stuff
}
}
相同之处在于它们不允许多个线程同时进入同步块;但是,这仅适用于类上的每个实例。即显示器打开this
类同步对Class
自身起作用,以下两个块也是等价的:
public static synchronized void putInCache() {
// ... do some stuff
cache.insert(this);
// ... do some more stuff
}
public void putInCache() {
synchronized(MyClass.class) {
// ... do some stuff
cache.insert(this);
// ... do some more stuff
}
}
它们根本不允许超过一个线程同时进入 JVM 上的同步块,即监视器在Class
实例上,因此是唯一的。
您需要使用Class
同步。
另一种方法是锁定资源本身,因为这是您试图阻止并发访问的内容;前提是资源不能为空并且资源的实例不会随机更改 - 如果final
您可以这样做,那就更好了:
public void putInCache() {
synchronized(cache) {
// ... do some stuff
cache.insert(this);
// ... do some more stuff
}
}
这使得您锁定的原因和锁定的内容非常清楚。