我有一个关于单例同步的问题。假设我有一个像这样的单例模式:
public class Singleton {
private final Object obj;
private static Singleton instance;
private Singleton(Object obj) {
this.obj = obj;
}
public static synchronized Singleton getInstance(Object obj) {
if (instance == null) {
instance = new Singleton(obj);
}
return instance;
}
public synchronized void methodA() {
// ...
}
public synchronized void methodB() {
// ...
}
}
我想同步对其的访问。我有两个假设需要验证。
假设: 由于所有方法(包括初始值设定项)都是同步的,因此对此 Singleton 的每次访问都是线程安全且同步的。
假设: 当我想确保一个线程想要调用
methodA()
然后立即调用methodB()
而没有另一个线程调用单例的方法时,同步是否正确在这样的实例上?
Singleton singleton = Singleton.getInstance(obj);
synchronized (singleton) {
singleton.methodA();
singleton.methodB();
}
说明:
1. 假设是否正确,因为非静态方法上的同步会在对象本身上进行同步,并且由于它始终是同一对象,因此访问是同步的?对 getInstance(obj)
的调用会在类本身上同步吗?
2. 假设是否正确,因为使用 getInstance(obj)
每个线程都会获取相同的对象,因此同步是正确的,因为另一个线程将等待同步块(synchronized block) (.. .methodA(); methodB();
) 是否退出?
最佳答案
假设我理解正确,你的假设是正确的。我只是想指出,在大多数情况下,您可以使用更简单的单例模式:
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
该字段将以线程安全的方式在第一个静态引用(例如 getInstance()
)上初始化,无需显式同步。
此外,实例
应该是最终
。
关于java - 单例上的同步访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30692116/