Singleton tasarım deseni, bir sınıfın sadece bir örneğinin oluşturulabileceğini ve bu örneğin her zaman aynı noktadan erişilebileceğini garanti eden bir tasarım desenidir. Bu tasarım deseni, genellikle bir sistemde sadece bir örneğinin tutulması gereken bir nesnenin oluşturulması için kullanılır. Örneğin, bir uygulamada bir veritabanı bağlantısının sadece bir örneğinin tutulması gerektiği durumlarda singleton tasarım deseni kullanılabilir.
Thread safe bir singleton tasarım deseni, çoklu threadlerin (çalıştırılan iş parçacıkları) aynı anda erişimine ve bu örneği değiştirmeye çalışmaları durumunda örneğin tek bir thread tarafından oluşturulmuş ve değiştirilmiş olmasını garanti eder. Bu, singleton örneğinin thread safe olmasını sağlar.
Thread safe olmayan bir singleton tasarım deseni ise çoklu threadlerin aynı anda erişimine ve bu örneği değiştirmeye çalışmaları durumunda örneğin birden fazla thread tarafından oluşturulmuş ve değiştirilmiş olabileceğini garanti etmez. Bu, singleton örneğinin thread safe olmayabileceği anlamına gelebilir.
Java‘da thread safe olmayan bir singleton tasarım deseni oluşturmak için aşağıdaki yöntemlerden biri kullanılabilir.
1-) Eager Initialization: Bu yöntemde, singleton nesne sınıfı ilk yüklenirken oluşturulur ve daha sonra hiçbir zaman tekrar oluşturulmaz. Bu yöntem, thread safe olmayan bir singleton örneği oluşturmak için kullanılabilir.
public class EagerInitializationSingleton {
private static final EagerInitializationSingleton instance = new EagerInitializationSingleton();
private EagerInitializationSingleton() {}
public static EagerInitializationSingleton getInstance() {
return instance;
}
}
2-) Lazy Initialization: Bu yöntemde, singleton nesne sadece ilk kez erişilmeye çalışıldığında oluşturulur. Bu yöntem, thread safe olmayan bir singleton örneği oluşturmak için kullanılabilir. Ancak, çoklu threadlerin aynı anda erişmeye çalıştıkları durumlarda birden fazla örnek oluşturulabileceği için bu yöntem pek tavsiye edilmez.
public class LazyInitializationSingleton {
private static LazyInitializationSingleton instance;
private LazyInitializationSingleton() {}
public static LazyInitializationSingleton getInstance() {
if (instance == null) {
instance = new LazyInitializationSingleton();
}
return instance;
}
}
Java’da thread safe bir singleton tasarım deseni oluşturmak için aşağıdaki yöntemlerden biri kullanılabilir.
1-) Double-Checked Locking: Bu yöntem, çoklu threadlerin aynı anda erişmeye çalıştıkları durumlarda singleton örneğinin birden fazla kez oluşturulmamasını sağlar. Bu yöntem, thread safe bir singleton örneği oluşturmak için kullanılabilir. Ancak, Java 5 ve öncesi sürümlerde bu yöntem performans sorunlarına yol açabildiği için tavsiye edilmez.
public class DoubleCheckedLockingSingleton {
private static volatile DoubleCheckedLockingSingleton instance;
private DoubleCheckedLockingSingleton() {}
public static DoubleCheckedLockingSingleton getInstance() {
if (instance == null) {
synchronized (DoubleCheckedLockingSingleton.class) {
if (instance == null) {
instance = new DoubleCheckedLockingSingleton();
}
}
}
return instance;
}
}
2-) Enum Singleton: Bu yöntem, Java Enum türlerini kullanarak singleton örneğinin oluşturulmasını sağlar. Bu yöntem, thread safe bir singleton örneği oluşturmak için en güvenli yöntemlerden biridir.
public enum EnumSingleton {
INSTANCE;
public static EnumSingleton getInstance() {
return INSTANCE;
}
}
3-) Bill Pugh Singleton: Bu yöntem, inner static class kullanılarak singleton örneğinin oluşturulmasını sağlar. Bu yöntem, JVM tarafından optimize edilerek thread safe bir singleton örneği oluşturulur.
public class BillPughSingleton {
private BillPughSingleton() {}
private static class SingletonHelper {
private static final BillPughSingleton INSTANCE = new BillPughSingleton();
}
public static BillPughSingleton getInstance() {
return SingletonHelper.INSTANCE;
}
}
Bir sonraki yazıda görüşmek üzere.