it-swarm-id.com

Singleton lazy vs instantiation

Jika singleton diterapkan sebagai berikut,

class Singleton {
    private static Singleton instance = new Singleton();

    public static Singleton getInstance() {
        return instance;
    }
}

Bagaimana implementasi ini berbeda dari pendekatan inisialisasi malas? Dalam kasus ini, instance akan dibuat ketika kelas dimuat dan kelas itu sendiri dimuat hanya pada penggunaan aktif pertama (misalnya, Singleton.getInstance ( ) tidak ketika Anda mendeklarasikan misalnya Singleton singleton = null;)

Bahkan dengan pendekatan inisialisasi malas, instance dibuat pada panggilan untuk getInstance ()

Apakah saya melewatkan sesuatu di sini?

22
java_geek

Anda dapat memanggil metode statis lain atau variabel anggota statis juga untuk memuat instance tunggal.

class Logger {     
   private static Logger instance = new Logger(); 
   public static String LOG_LINE_SEPERATOR =  
      System.getProperty("line.separator");
   public static Logger getInstance() {  
          return instance;     
   } 

   public static String logPattern() {
       return null;
   }
} 

...

Logger.LOG_LINE_SEPERATOR; // load Logger instance or
Logger.logPattern(); // load Logger instance
12

Dengan inisialisasi malas Anda membuat contoh hanya ketika dibutuhkan dan bukan ketika kelas dimuat. Jadi Anda lolos dari penciptaan objek yang tidak perlu. Yang sedang berkata ada hal-hal lain untuk dipertimbangkan juga. Dalam inisialisasi malas Anda memberikan API publik untuk mendapatkan contoh. Dalam lingkungan multi-utas itu menimbulkan tantangan untuk menghindari pembuatan objek yang tidak perlu. Anda menempatkan blok sinkronisasi yang menimbulkan penguncian yang tidak perlu dilakukan untuk memeriksa objek yang sudah dibuat. Jadi itu menjadi masalah kinerja dalam hal ini. 

Jadi, jika Anda yakin bahwa membuat objek Anda tidak akan mengambil memori yang signifikan dan hampir selalu akan digunakan dalam aplikasi Anda maka bagus untuk membuat inisialisasi statis. Juga jangan lupa untuk membuat instance Anda final dalam kasus ini karena memastikan bahwa pembuatan objek tercermin dengan benar dan totalitas ke memori utama yang penting dalam lingkungan multi-threaded.

Silakan lihat tutorial ini dari IBM tentang kasus Singleton + Lazy Loading + Multithreaded Environment

=============== Edit pada 09/09/2018 ====================

Anda juga harus melihat pembuatan objek pada pola permintaan sini .

18
Saurabh

Untuk alasan yang Anda sebutkan, ini hanya cara yang lebih rumit untuk melakukan hal yang sama

enum Singleton {
    INSTANCE;
}

Menggunakan inisialisasi lazy hanya berguna jika Anda khawatir bahwa kelas dapat diinitilisasikan tetapi Anda tidak ingin memuat singleton pada saat itu. Untuk sebagian besar situasi ini sudah berakhir membunuh.

Catatan: Hanya mereferensikan kelas tidak menginisialisasi kelas.

misalnya Katakanlah Anda memiliki kelas yang ditulis dengan buruk yang tidak dapat diinisialisasi sampai beberapa kondisi ditetapkan. Dalam hal ini n harus bukan nol.

public class Main {
    public static void main(String ... args) {
        Class c= LazyLoaded.class;
        System.out.println(c);
    }

    static class LazyLoaded {
        static int n = 0;
        static {
            System.out.println("Inverse "+1000/n);
        }
    }
}

cetakan

class Main$LazyLoaded
6
Peter Lawrey

Pertama-tama, pola singleton terlalu sering digunakan. Apa yang benar-benar ingin Anda lakukan jika Anda ingin "salah satu dari sesuatu" adalah menyatakannya sebagai singleton dalam kerangka pilihan DI Anda. Ini secara efektif adalah konfigurasi yang didorong oleh singleton, dan membebaskan opsi untuk menginjeksi tiruan untuk melakukan pengujian yang tepat. 

Mengapa tidak memuat malas? Kecuali kelas Anda memiliki rutin inisialisasi besar-besaran dalam konstruksi (yang saya berpendapat juga merupakan anti-pola), tidak ada manfaat dan banyak kekurangan untuk pemuatan malas. Anda hanya menambahkan kompleksitas dan mungkin merusak program Anda jika tidak dilakukan dengan benar. Cara yang benar (jika Anda harus) adalah menggunakan idiom pemegang Inisialisasi sesuai permintaan. 

0
Travis

Untuk contoh pemuatan tunggal yang malas, saya menggunakan seperti di bawah ini.

class Singleton {
private static Singleton instance;
private Singleton(){

}
public static Singleton getInstance() {
    if(null==instance){
        synchronized(Singleton.class){
            if(null==instance){
                instance = new Singleton();
            }
        }
    }
    return instance;
}
}
0
Brijesh