Tembel başlatma, kaynakların kullanımını optimize etmek için tarihsel olarak ortaya çıkmıştır; bu, bir nesnenin yalnızca gerçekten ihtiyaç duyulduğunda oluşturulması anlamına gelir. Başlangıçta, bu, ağır nesneler, bağlantılar, önbellekler veya karmaşık kalıpların (örneğin, Singleton) uygulanmasıyla çalışırken önemliydi.
Sorun şu ki, tüm kaynakları hemen oluşturmak gereksiz bellek, zaman ve işlem gücü harcamasına neden olabilir, hatta nesneye ihtiyaç duyulmadığında bile. Tembel başlatma, "ertelenmiş" yaratma sorununu çözer.
Çözüm genellikle bir kontrol ile uygulanır: Eğer nesne henüz oluşturulmadıysa, onu oluştururuz, aksi takdirde mevcut olanı döndürürüz.
Kod örneği:
public class LazyHolder { private Resource resource; public Resource getResource() { if (resource == null) { resource = new Resource(); } return resource; } }
Çok iş parçacıklı ortamlarda senkronizasyon gereklidir.
Anahtar özellikler:
Double-Checked Locking, tembel başlatma için güvenilir bir uygulama mıdır?
Ancak Java 5 ile birlikte, çünkü daha önce bellek modeli bunu garanti etmiyordu. Kaynak alanı için volatile anahtar kelimesi kullanmak gereklidir.
private volatile Resource resource; public Resource getResource() { if (resource == null) { synchronized(this) { if (resource == null) { resource = new Resource(); } } } return resource; }
Hafif nesneler için tembel başlatma yapmak mantıklı mı?
Genellikle hayır. "Hafif" nesneleri hemen oluşturmak, kodun okunabilirliğini azaltmamak ve gereksiz mantıkla karmaşıklaştırmamak için daha iyidir.
Tembel başlatma, nesnelerin serileştirilmesi sırasında çalışır mı?
Her zaman değil. Serileştirildiğinde "eski" bir durum geri yüklenebilir veya readObject() içinde ek mantık gerektirebilir.
Yüksek yük servisinde özel bir nesne havuzu tembel olarak ayrıştırıldı, ancak senkronize edilmedi. İki iş parçacığı aynı anda bir nesneyi başlattı ve bu hafıza sızıntılarına ve öngörülemeyen hatalara yol açtı.
Artılar:
Eksiler:
Büyük bir web uygulamasında analitik, sadece bir API çağrısı ile tembel başlatılan bir proxy nesnesi aracılığıyla bağlanır ve double-checked locking ile gerçekleştirilir.
Artılar:
Eksiler: