Kla*_*Nji 8 java singleton synchronization
是否需要将synchronize关键字应用于实现单例模式的类的每个方法?
public class Singleton {
private Singleton(){}
public synchronized static Singleton getInstance()
{
if(instance == null)
instance = new Singleton ();
return instance;
}
public void DoA(){
}
}
Run Code Online (Sandbox Code Playgroud)
由于Singletons不公开公共构造函数并且getInstance()方法是同步的,因此不需要同步方法DoA和Singleton类公开的任何其他公共方法.
这个推理是否正确?
NPE*_*NPE 19
它就像任何其他类一样.它可能需要或可能不需要进一步同步.
请考虑以下示例:
public class Singleton {
private Singleton() {}
public synchronized static Singleton getInstance() { ... }
private int counter = 0;
public void addToCounter(int val) {
counter += val;
}
}
Run Code Online (Sandbox Code Playgroud)
如果要从多个线程使用该类,addToCounter()
则具有竞争条件.解决这个问题的一种方法是addToCounter()
同步:
public synchronized void addToCounter(int val) {
count += val;
}
Run Code Online (Sandbox Code Playgroud)
还有其他方法可以修复竞争条件,例如使用AtomicInteger
:
private final AtomicInteger counter = new AtomicInteger(0);
public void addToCounter(int val) {
counter.addAndGet(val);
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们已经修复了比赛条件而没有使用synchronized
.
Del*_*ima 10
好吧,Singleton类的目的是它最多只有一个实例,所有Threads都可以访问同一个对象.
如果您不同步该getInstance
方法,则可能发生以下情况
Thread1进入 getInstance()
Thread2进入 getInstance()
Thread1评估instance == null
为true
Thread2评估instance == null
为true
Thread1分配instance
并返回
Thread2 重新分配instance = new Singleton()
并返回.
现在线程都有一个Singleton类的不同实例,这是该模式应该阻止的.
同步可防止两个线程同时访问同一代码块.因此,在实例化单例类时,多线程环境中需要同步.
现在假设多个线程将同时尝试访问Singletons方法,同样可能需要同步这些方法.特别是如果他们改变数据而不是只读它,这是真的.
归档时间: |
|
查看次数: |
18505 次 |
最近记录: |