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.
KelasSingleObject menyediakan kaedah statik untuk dunia luar mendapatkan contoh statiknya. SingletonPatternDemo, kelas demo kami menggunakan kelas SingleObject untuk mendapatkan objek SingleObject.

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 benangSama 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; } }
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.
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)
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. Contoh kod: 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. Contoh kod: 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. Contoh kod: 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.
Prestasi getInstance() adalah penting untuk aplikasi. 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
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. 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
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.