Corak singleton


Corak Singleton ialah salah satu corak reka bentuk yang paling mudah di Jawa. Corak reka bentuk jenis ini ialah corak ciptaan, yang menyediakan cara optimum untuk mencipta objek.

Corak ini melibatkan satu kelas yang bertanggungjawab untuk mencipta objeknya sendiri sambil memastikan hanya satu objek dicipta. Kelas ini menyediakan cara untuk mengakses objek uniknya secara langsung, tanpa perlu membuat instantiate objek kelas.

Nota:

  • 1. Kelas tunggal hanya boleh mempunyai satu contoh.

  • 2. Kelas tunggal mesti mencipta contoh uniknya sendiri.

  • 3. Kelas tunggal mesti menyediakan kejadian ini kepada semua objek lain.


Pengenalan

Niat: Jaminan bahawa kelas hanya mempunyai satu contoh dan menyediakan cara untuk mengakses ia Titik capaian global.

Penyelesaian utama: Kelas yang digunakan secara global sering dibuat dan dimusnahkan.

Bila hendak digunakan: Apabila anda mahu mengawal bilangan kejadian dan menjimatkan sumber sistem.

Cara menyelesaikan: Tentukan sama ada sistem sudah mempunyai singleton ini, jika ya, pulangkan, jika tidak, buatnya.

Kod kunci: Pembina adalah peribadi.

Contoh permohonan: 1. 2. Windows adalah berbilang proses dan berbilang benang Apabila mengendalikan fail, tidak dapat dielakkan bahawa berbilang proses atau benang mengendalikan fail pada masa yang sama, semua pemprosesan fail mesti dilakukan melalui contoh yang unik. 3. Sesetengah pengurus peranti sering direka dalam mod tunggal Contohnya, jika komputer mempunyai dua pencetak, ia mesti diproses apabila mengeluarkan dua pencetak tidak boleh mencetak fail yang sama.

Kelebihan: 1. Hanya terdapat satu kejadian dalam ingatan, yang mengurangkan overhed memori, terutamanya apabila kejadian kerap dibuat dan dimusnahkan (seperti cache halaman utama Sekolah Pengurusan). 2. Elakkan pelbagai pekerjaan sumber (seperti operasi menulis fail).

Kelemahan: Tiada antara muka dan tidak boleh diwarisi, yang bercanggah dengan prinsip tanggungjawab tunggal Kelas hanya perlu mengambil berat tentang logik dalaman dan bukan cara untuk mewujudkannya di luar.

Senario penggunaan: 1. Memerlukan pengeluaran nombor siri yang unik. 2. Kaunter dalam WEB tidak perlu ditambah ke pangkalan data setiap kali ia dimuat semula Ia dicache terlebih dahulu dengan satu contoh. 3. Objek yang dicipta menggunakan terlalu banyak sumber, seperti I/O dan sambungan pangkalan data.

Nota: Kunci penyegerakan yang disegerakkan (Singleton.class) perlu digunakan dalam kaedah getInstance() untuk menghalang berbilang utas daripada masuk pada masa yang sama dan menyebabkan kejadian itu dijadikan instantiated beberapa kali.

Pelaksanaan

Kami akan mencipta kelas SingleObject. Kelas SingleObject mempunyai pembina peribadi dan contoh statik sendiri.

Kelas

SingleObject menyediakan kaedah statik untuk dunia luar mendapatkan contoh statiknya. SingletonPatternDemo, kelas demo kami menggunakan kelas SingleObject untuk mendapatkan objek SingleObject.

单例模式的 UML 图

Langkah 1

Buat kelas Singleton.

SingleObject.java

public class SingleObject {

   //创建 SingleObject 的一个对象
   private static SingleObject instance = new SingleObject();

   //让构造函数为 private,这样该类就不会被实例化
   private SingleObject(){}

   //获取唯一可用的对象
   public static SingleObject getInstance(){
      return instance;
   }

   public void showMessage(){
      System.out.println("Hello World!");
   }
}

Langkah 2

Dapatkan objek unik daripada kelas singleton.

SingletonPatternDemo.java

public class SingletonPatternDemo {
   public static void main(String[] args) {

      //不合法的构造函数
      //编译时错误:构造函数 SingleObject() 是不可见的
      //SingleObject object = new SingleObject();

      //获取唯一可用的对象
      SingleObject object = SingleObject.getInstance();

      //显示消息
      object.showMessage();
   }
}

Langkah 3

Sahkan output.

Hello World!

Beberapa cara untuk melaksanakan corak tunggal

Terdapat banyak cara untuk melaksanakan corak tunggal, seperti yang ditunjukkan di bawah:

1

Sama ada Pemulaan Malas: Ya

Sama ada ia selamat berbilang benang: Tidak

Kesukaran pelaksanaan: Mudah

Penerangan: Kaedah ini merupakan kaedah pelaksanaan yang paling asas Masalah terbesar dengan pelaksanaan ini ialah ia tidak menyokong multi-threading. Kerana tiada kunci yang disegerakkan, ia tidak dianggap sebagai mod tunggal dalam erti kata yang ketat. Kaedah pemuatan malas ini jelas tidak memerlukan keselamatan benang dan tidak akan berfungsi dengan baik dengan berbilang benang.

Contoh kod:

public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  
  
    public static Singleton getInstance() {  
    if (instance == null) {  
        instance = new Singleton();  
    }  
    return instance;  
    }  
}


Kaedah pelaksanaan yang diperkenalkan seterusnya semua menyokong multi-threading, tetapi dalam prestasi Terdapat satu perbezaan.

2. Gaya malas, selamat benang

Sama ada pengamulaan Malas: Ya

Sama ada ia selamat berbilang benang : Ya

Kesukaran pelaksanaan: Mudah

Penerangan: Kaedah ini mempunyai pemuatan malas yang baik dan boleh berfungsi dengan baik dalam berbilang benang , bagaimanapun, kecekapannya sangat rendah, dan penyegerakan tidak diperlukan dalam 99% kes. Kelebihan: Ia hanya dimulakan pada panggilan pertama untuk mengelakkan pembaziran memori.
Kelemahan: disegerakkan mesti dikunci untuk memastikan tunggal, tetapi penguncian akan menjejaskan kecekapan.
Prestasi getInstance() tidak kritikal kepada aplikasi (kaedah ini digunakan kurang kerap).

Contoh kod:

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


3 Gaya Cina Lapar

Sama ada pemulaan Lazy: <. 🎜>Tidak

Adakah ia selamat berbilang benang:

Ya

Kesukaran pelaksanaan:

Mudah

Penerangan :

Kaedah ini lebih biasa digunakan, tetapi ia mudah untuk menghasilkan objek sampah. Kelebihan: Tiada penguncian, kecekapan pelaksanaan akan dipertingkatkan. Kelemahan: Kelas dimulakan apabila memuatkan, yang membazirkan ingatan.
Ia berdasarkan mekanisme classloder untuk mengelakkan masalah penyegerakan berbilang benang Walau bagaimanapun, instance diwujudkan apabila kelas dimuatkan Walaupun terdapat banyak sebab untuk pemuatan kelas, kebanyakannya memanggil kaedah getInstance dalam mod tunggal. tetapi Ia juga tidak pasti bahawa terdapat cara lain (atau kaedah statik lain) yang menyebabkan pemuatan kelas Pada masa ini, memulakan contoh jelas tidak mencapai kesan pemuatan malas.

Contoh kod:

public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
    return instance;  
    }  
}


4. Periksa semula kunci/kunci semak dua kali (DCL, penguncian semak dua kali)

Versi JDK:

JDK1.5 dan ke atas

Sama ada pemulaan Lazy:

Ya

Sama ada ia selamat berbilang benang: Ya

Kesukaran pelaksanaan: Lebih kompleks

Penerangan: Kaedah ini digunakan Mekanisme kunci berganda, selamat dan mampu mengekalkan prestasi tinggi dalam situasi berbilang benang.
Prestasi getInstance() adalah penting untuk aplikasi.

Contoh kod:

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  
        synchronized (Singleton.class) {  
        if (singleton == null) {  
            singleton = new Singleton();  
        }  
        }  
    }  
    return singleton;  
    }  
}


5. Kelas dalaman berdaftar/statik

Sama ada Permulaan Malas : Ya

Sama ada ia selamat berbilang benang: Ya

Kesukaran pelaksanaan: Umum

Penerangan :Kaedah ini boleh mencapai kesan yang sama seperti kaedah kunci semak dua kali, tetapi pelaksanaannya lebih mudah. Gunakan permulaan malas untuk medan statik Kaedah ini harus digunakan dan bukannya kaedah kunci semak dua kali. Kaedah ini hanya terpakai pada domain statik Kaedah kunci semak dua kali boleh digunakan apabila domain contoh memerlukan pengamulaan tertunda.
Kaedah ini juga menggunakan mekanisme classloder untuk memastikan bahawa terdapat hanya satu utas semasa memulakan tika Ia berbeza daripada kaedah ketiga: dalam kaedah ketiga, selagi kelas Singleton dimuatkan, tika itu akan dijadikan instantiated. (tidak Untuk mencapai kesan pemuatan malas), dengan cara ini, kelas Singleton dimuatkan dan contoh tidak semestinya dimulakan. Oleh kerana kelas SingletonHolder tidak digunakan secara aktif, kelas SingletonHolder hanya akan dimuatkan secara eksplisit dengan memanggil kaedah getInstance untuk membuat instance contoh. Bayangkan jika membuat instantiat contoh menggunakan sumber, jadi anda mahu ia dimuatkan dengan malas Sebaliknya, anda tidak mahu membuat instantiat apabila kelas Singleton dimuatkan, kerana tiada jaminan bahawa kelas Singleton boleh digunakan secara aktif. di tempat lain dan dengan itu dimuatkan, maka jelas sekali tidak sesuai untuk membuat contoh pada masa ini. Pada masa ini, kaedah ini kelihatan lebih munasabah daripada kaedah ketiga.

Contoh kod:

public class Singleton {  
    private static class SingletonHolder {  
    private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
    return SingletonHolder.INSTANCE;  
    }  
}


6 Penghitungan

Versi JDK: Bermula. daripada JDK1.5

Sama ada untuk menjadi Malas dimulakan: Tidak

Sama ada untuk selamat berbilang benang: Ya

Kesukaran pelaksanaan :Mudah

Penerangan: Pelaksanaan ini belum diterima pakai secara meluas, tetapi ia adalah cara terbaik untuk melaksanakan corak tunggal. Ia lebih ringkas, secara automatik menyokong mekanisme bersiri, dan benar-benar menghalang pelbagai instantiasi.
Kaedah ini dianjurkan oleh pengarang Java Berkesan Josh Bloch Ia bukan sahaja mengelakkan masalah penyegerakan berbilang benang, tetapi juga secara automatik menyokong mekanisme bersiri untuk menghalang penyahserikan daripada mencipta semula objek baharu dan benar-benar menghalang berbilang instantiasi. Walau bagaimanapun, memandangkan ciri enum hanya ditambahkan selepas JDK1.5, penulisan dengan cara ini membuatkan orang berasa asing, dan ia jarang digunakan dalam kerja sebenar.
Pembina peribadi tidak boleh dipanggil melalui serangan refleksi.

Contoh kod:

rreee


Pengalaman: Secara amnya, tidak digalakkan menggunakan kaedah malas pertama dan kedua, dan disyorkan menggunakan kaedah lapar ke-3. Kaedah pendaftaran kelima hanya akan digunakan apabila kesan pemuatan malas dilaksanakan secara eksplisit. Jika ia melibatkan penyahserikatan dan mencipta objek, anda boleh mencuba kaedah penghitungan keenam. Jika anda mempunyai keperluan khas lain, anda boleh mempertimbangkan untuk menggunakan kaedah kunci semakan dua kali keempat.