Java以单例模式同步

是否需要将synchronize关键字应用于实现单例模式的类的每个方法?

public class Singleton { private Singleton(){} public synchronized static Singleton getInstance() { if(instance == null) instance = new Singleton (); return instance; } public void DoA(){ } } 

由于Singletons不公开公共构造函数并且getInstance()方法是同步的,因此不需要同步方法DoA和Singleton类公开的任何其他公共方法。

这个推理是否正确?

它就像任何其他类一样。 它可能需要或可能不需要进一步同步。

请考虑以下示例:

 public class Singleton { private Singleton() {} public synchronized static Singleton getInstance() { ... } private int counter = 0; public void addToCounter(int val) { counter += val; } } 

如果要从多个线程使用该类,则addToCounter()具有竞争条件。 解决这个问题的一种方法是使addToCounter()同步:

  public synchronized void addToCounter(int val) { count += val; } 

还有其他方法可以修复竞争条件,例如使用AtomicInteger

  private final AtomicInteger counter = new AtomicInteger(0); public void addToCounter(int val) { counter.addAndGet(val); } 

在这里,我们已经修复了竞争条件而不使用synchronized

好吧,Singleton类的目的是它最多只有一个实例,所有Threads都可以访问同一个对象。

如果您不同步getInstance方法,则可能发生以下情况

Thread1进入getInstance()

Thread2进入getInstance()

Thread1将instance == nulltrue

Thread2将instance == nulltrue

Thread1分配instance并返回

Thread2 重新分配instance = new Singleton()并返回。

现在线程都有一个Singleton类的不同实例,这是该模式应该阻止的。

同步可防止两个线程同时访问同一个代码块。 因此,在实例化单例类时,在multithreading环境中需要同步。

现在假设多个线程将同时尝试访问Singletons方法,同样可能需要同步这些方法。 特别是如果他们改变数据而不是只读它,这是真的。

使用Singleton的正确(最佳实际)方式

 private static singleton getInstance() { if (minstance == null) { synchronized (singleton.class) { if (minstance == null) { minstance = new singleton(); } } } return minstance; } 

延迟初始化和线程安全解决方案:

 public class Singleton { public static class SingletonHolder { public static final Singleton HOLDER_INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.HOLDER_INSTANCE; } }