Evet gerekli. Geç başlatma ile iş parçacığı güvenliğini sağlamak için kullanabileceğiniz birkaç yöntem vardır:
Acımasız senkronizasyon:
private static YourObject instance;
public static synchronized YourObject getInstance() {
if (instance == null) {
instance = new YourObject();
}
return instance;
}
Bu çözüm, gerçekte sadece ilk birkaçının olması gerektiğinde her iş parçacığının senkronize edilmesini gerektirir.
Senkronizasyonu iki kez kontrol edin :
private static final Object lock = new Object();
private static volatile YourObject instance;
public static YourObject getInstance() {
YourObject r = instance;
if (r == null) {
synchronized (lock) { // While we were waiting for the lock, another
r = instance; // thread may have instantiated the object.
if (r == null) {
r = new YourObject();
instance = r;
}
}
}
return r;
}
Bu çözüm, yalnızca singletonunuzu almaya çalışan ilk birkaç iş parçacığının kilidi edinme sürecinden geçmesini sağlar.
Talep Üzerine Başlatma :
private static class InstanceHolder {
private static final YourObject instance = new YourObject();
}
public static YourObject getInstance() {
return InstanceHolder.instance;
}
Bu çözüm, iş parçacığı güvenliğini sağlamak için Java bellek modelinin sınıf başlatma garantilerinden yararlanır. Her sınıf yalnızca bir kez yüklenebilir ve yalnızca ihtiyaç duyulduğunda yüklenecektir. Bu, ilk seferin getInstance
çağrılacağı, InstanceHolder
yükleneceği ve instance
oluşturulacağı anlamına gelir ve bu, ClassLoader
s tarafından kontrol edildiğinden , ek senkronizasyon gerekmez.