java Java以单例模式同步
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15930633/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java synchronize in singleton pattern
提问by Klaus Nji
Does the synchronize keyword need to be applied to each method of a class that implements the singleton pattern like this?
是否需要将同步关键字应用于实现单例模式的类的每个方法?
public class Singleton {
private Singleton(){}
public synchronized static Singleton getInstance()
{
if(instance == null)
instance = new Singleton ();
return instance;
}
public void DoA(){
}
}
Since Singletons don't expose a public constructor and the getInstance() method is synchronized, one does not need to synchronize method DoA and any other public methods exposed by the Singleton class.
由于 Singleton 不公开公共构造函数并且 getInstance() 方法是同步的,因此不需要同步方法 DoA 和 Singleton 类公开的任何其他公共方法。
Is this reasoning correct?
这个推理正确吗?
回答by NPE
It's just like any other class. It may or may not need further synchronization.
这就像任何其他课程一样。它可能需要也可能不需要进一步的同步。
Consider the following example:
考虑以下示例:
public class Singleton {
private Singleton() {}
public synchronized static Singleton getInstance() { ... }
private int counter = 0;
public void addToCounter(int val) {
counter += val;
}
}
If the class is to be used from multiple threads, addToCounter()has a race condition. One way to fix that is by making addToCounter()synchronized:
如果要从多个线程使用该类,addToCounter()则具有竞争条件。解决此问题的一种方法是进行addToCounter()同步:
public synchronized void addToCounter(int val) {
count += val;
}
There are other ways to fix the race condition, for example by using AtomicInteger:
还有其他方法可以修复竞争条件,例如使用AtomicInteger:
private final AtomicInteger counter = new AtomicInteger(0);
public void addToCounter(int val) {
counter.addAndGet(val);
}
Here, we've fixed the race condition without using synchronized.
在这里,我们在不使用synchronized.
回答by DeltaLima
Well, the purpose of the Singleton class is that there is at most one instance of it and that all Threads can access that same object.
好吧,Singleton 类的目的是它最多只有一个实例,并且所有线程都可以访问同一个对象。
If you would not synchronize the getInstancemethod the following could happen
如果您不同步该getInstance方法,则可能会发生以下情况
Thread1 enters getInstance()
线程1进入 getInstance()
Thread2 enters getInstance()
线程2进入 getInstance()
Thread1 evaluates instance == nullto true
Thread1 评估instance == null为true
Thread2 evaluates instance == nullto true
Thread2 评估instance == null为true
Thread1 assigns instanceand returns
Thread1 赋值instance和返回
Thread2 reassigns instance = new Singleton()and returns.
Thread2重新分配instance = new Singleton()并返回。
Now the threads both have a difference instance of the Singleton class which is what should have been prevented by this pattern.
现在这两个线程都有一个 Singleton 类的不同实例,这是这种模式应该阻止的。
Synchronizing prevents that both Threads can access the same block of code at the same time. So synchronization is needed in a multithreaded environment when you instantiate singleton classes.
同步防止两个线程可以同时访问同一个代码块。因此,当您实例化单例类时,在多线程环境中需要同步。
Now assuming that multiple threads will attempt to access the Singletons methods at the same time synchronization might be necessary on those methods as well. Especially if they change data instead of only reading it this is true.
现在假设多个线程将尝试同时访问 Singletons 方法,这些方法也可能需要同步。特别是如果他们更改数据而不是只读取数据,这是真的。
回答by gaurav414u
The correct(Best actually) way to use Singleton
使用 Singleton 的正确(实际上是最好的)方法
private static singleton getInstance() {
if (minstance == null) {
synchronized (singleton.class) {
if (minstance == null) {
minstance = new singleton();
}
}
}
return minstance;
}
回答by Flinbor
lazy initialization and thread safe solution:
延迟初始化和线程安全解决方案:
public class Singleton {
public static class SingletonHolder {
public static final Singleton HOLDER_INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.HOLDER_INSTANCE;
}
}

