Son zamanlarda tembel nesneleri (ilk erişimi üzerindeki iç durumunu yarattı olacak nesneler) oluşturmak için bir yol tanıtıldı bir makale "Be Lazy With Java 8", okuyun.Klasik tekil
public final class Lazy<T> {
private volatile T value;
public T getOrCompute(Supplier<T> supplier){
final T result = value;
return result == null ? maybeCompute(supplier) : result;
}
private synchronized T maybeCompute(Supplier<T> supplier) {
if (value == null){
value = Objects.requireNonNull(supplier.get());
}
return value;
}
}
Bu model jenerik dışında iyi bilinen tekil desen çok benzer olduğu bulunmuştur:
public class PropertiesSingleton {
public static Properties getProperties(){
return Helper.INSTANCE;
}
private final static class Helper{
private final static Properties INSTANCE = computeWithClassLoaderLock();
private static Properties computeWithClassLoaderLock(){
return new Properties();
}
}
}
Tembel sınıf iç nesne süre erişimi eşitlemek için uçucu elemanı kullanır singleton modelinin birkaç uygulaması vardır (kişisel olarak bir statik final üyesi olan iç yardımcı sınıfıyla kullanmayı tercih ediyorum). Singleton L1 & L2 Önbellektekileri sınıf yükleyici önbelleğe ile bir kez yüklenir ise ikinci desen (Uçucu elemanına), ana bellek bir okuma içeren Tembel nesnesinde getOrCompute yönteme her çağrı yana daha iyi bir performans varsayılmıştır. Ben Intel (R) Core (TM) i5-3470 işlemci @ 3.20GHz ile CentOS 6 benim varsayımını test etmek için JMH kriter kullanılır. kriter benim Git deposundan indirilebilir:
Benchmark Mode Cnt Score Error Units
LazyVsSingletonPerformance.testLazy sample 1101716 33.793 ± 0.148 ns/op
LazyVsSingletonPerformance.testSingleton sample 622603 33.993 ± 0.179 ns/op
sonuç iki seçenek arasında hiçbir fark, nedenini anlamak değilim olduğunu göstermektedir: Burada
https://github.com/maximkir/LazyObjectVsSingletonPerformance sonuç tablosu vardır. İkinci modelin daha iyi performans göstermesini beklerdim. Herhangi bir fikir? inlining? Derleyici optimizasyonu? Yanlış karşılaştırma testi?
Benchmark kodu:
@State(Scope.Thread)
public class LazyVsSingletonPerformance {
Blackhole bh = new Blackhole();
Lazy<Properties> lazyProperties = new Lazy<>();
public static void main(String... args) throws Exception{
Options opts = new OptionsBuilder()
.include(LazyVsSingletonPerformance.class.getSimpleName())
.warmupIterations(3)
.forks(2)
.measurementIterations(3)
.mode(Mode.SampleTime)
.measurementTime(TimeValue.seconds(10))
.timeUnit(TimeUnit.NANOSECONDS)
.build();
new Runner(opts).run();
}
@Benchmark
public void testLazy(){
bh.consume(lazyProperties.getOrCompute(() -> new Properties()));
}
@Benchmark
public void testSingleton(){
bh.consume(PropertiesSingleton.getProperties());
}
Sonuçlar DZone yazı için orijinal kaynağıdır: http://minborgsjavapot.blogspot.com/2016/01/be-lazy- ile-java-8.html – srborlongan
bana öyle görünüyor - sıcak kadar sonra - nihayet sadece (hiç değişmez ve boş değil) uçucu üyesi herhangi birine erişimi veya tutucu sınıfının sabit üyesine karşılaştırın.Yani bu üyelerin başlangıç bölümlerini gerçekten ölçemiyorsunuz (çok sayıda çağrıştan sonra). –
Başlatma, yalnızca bir kez gerçekleştiği için önemli değildir. –