经过一番快速搜索,我无法找到明确的答案.
是否有一些更优雅的方法来同步整个类的整个成员方法(绑定在实例上)?这意味着可以通过多个线程在多个实例上调用方法,但是当时只能由一个线程调用.它也可以写为同步块.
(例如,该方法将其实例插入共享缓存中.)
class DataObject {
public putInCache() {
synchronized(getClass()) {
// ... do some stuff
cache.insert(this);
// ... do some more stuff
}
}
}
Run Code Online (Sandbox Code Playgroud)
避免在可公开访问的对象上进行同步是个好主意.但是,您可以使用共享监视器对象:
class DataObject {
private static final Object cacheLock = new Object();
public putInCache() {
synchronized(cacheLock) {
// ... do some stuff
cache.insert(this);
// ... do some more stuff
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,使用此特定实现DataObject,从其派生的所有类将共享锁.
Class和instance同步之间存在差异.
实例同步适用于每个实例Object,因此代码:
public synchronized void putInCache() {
// ... do some stuff
cache.insert(this);
// ... do some more stuff
}
Run Code Online (Sandbox Code Playgroud)
和代码
public void putInCache() {
synchronized(this) {
// ... do some stuff
cache.insert(this);
// ... do some more stuff
}
}
Run Code Online (Sandbox Code Playgroud)
相当于它们不允许多个线程同时进入同步块; 但是这仅适用于课程中的每个实例.即显示器已打开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
}
}
Run Code Online (Sandbox Code Playgroud)
它们不允许多个线程同时在JVM上同时进入同步块,即监视器位于Class实例上且非常独特.
您需要使用Class同步.
另一种方法是锁定资源本身,因为这是您试图阻止并发访问的内容; 如果资源不能为null,并且资源的实例不会随机更改 - 如果final您可以执行此操作,则更好:
public void putInCache() {
synchronized(cache) {
// ... do some stuff
cache.insert(this);
// ... do some more stuff
}
}
Run Code Online (Sandbox Code Playgroud)
这清楚地说明了为什么要锁定以及锁定什么.