经过一番快速搜索,我无法找到明确的答案。
有没有更优雅的方法来同步整个类的整个成员方法(绑定在实例上)?这意味着可以通过多个线程在多个实例上调用方法,但是当时只能由一个线程调用。它也可以写成同步块。
(例如,该方法将其实例插入共享缓存中。)
class DataObject {
public putInCache() {
synchronized(getClass()) {
// ... do some stuff
cache.insert(this);
// ... do some more stuff
}
}
}
答案 0 :(得分:6)
避免在可公开访问的对象上进行同步是个好主意。但是,您可以使用共享监视器对象:
class DataObject {
private static final Object cacheLock = new Object();
public putInCache() {
synchronized(cacheLock) {
// ... do some stuff
cache.insert(this);
// ... do some more stuff
}
}
}
请注意,使用此特定实现DataObject
并从其派生的所有类将共享锁。
答案 1 :(得分:5)
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
同步。
另一种方法是锁定资源本身,因为这是您试图阻止并发访问的内容;如果资源不能为null,并且资源的实例不会随机更改 - 如果final
可以执行此操作,那就更好了:
public void putInCache() {
synchronized(cache) {
// ... do some stuff
cache.insert(this);
// ... do some more stuff
}
}
这清楚地说明了为什么要锁定以及锁定什么。
答案 2 :(得分:0)
我猜你正在寻找班级同步。尝试使该方法成为静态和同步的方法。 例如:
public synchronized static putInCache(){
//..your code
}
这意味着“可以通过多个线程在多个实例上调用方法,但当时只能由一个线程调用。”