Tujuan dari pola singleton adalah untuk memastikan bahwa kelas hanya memiliki satu contoh dan juga memberikan titik akses global untuk itu. Untuk mencegah pekerja lain instantiasi kelas kami,
Anda dapat membuat konstruktor yang unik untuk kelas ini dan mengatur konstruktor yang terlihat menjadi pribadi. Perlu dicatat bahwa jika kita membuat konstruktor non-pribadi lainnya, atau kita tidak menyebutkan kelas sama sekali
Untuk konstruktor, maka orang lain masih dapat membuat kelas kami. Jika kita tidak ingin membuat objek singleton terlebih dahulu, kita bisa menunggu sampai pertama kali kita menggunakan objek singleton, yaitu,
Inisialisasi lag. Ada dua alasan untuk inisialisasi objek singleton yang tertinggal:
1. Mungkin pada waktu inisialisasi statis, Anda tidak memiliki informasi yang cukup tentang cara menginisialisasi objek singleton.
2. Tujuan memilih inisialisasi lag Singleton mungkin menunggu sumber daya seperti koneksi basis data, terutama dalam aplikasi di mana singleton ini tidak diperlukan dalam sesi spesifik tertentu.
Jika singleton diinisialisasi dalam lingkungan multithreaded, kita harus berhati -hati untuk mencegah beberapa utas dari menginisialisasi waktu yang sama.
Biasanya, pola singleton dibangun dalam bahasa java:
Lazy Way: Mengacu pada instance singleton global yang sedang dibangun saat digunakan untuk pertama kalinya. Tunda inisialisasi.
Metode Hungry Man: Mengacu pada instance tunggal global yang sedang dibangun selama pemuatan kelas. Inisialisasi yang mendesak.
1. Singleton Cina lapar
Public Class Singleton1 {private singleton1 () {} // Tentukan contoh Anda sendiri secara internal. // Perhatikan bahwa ini pribadi. Private static singleton1 instance = new Singleton1 (); /** * // ** * Berikut adalah metode statis untuk akses eksternal ke kelas ini, yang dapat diakses secara langsung * @return */public static singleton1 getInstance () {instance return; }}2. Kelas Singleton Malas
kelas publik singleton2 {private static singleton2 instance = null; /*** // *** Metode ini ditingkatkan dibandingkan dengan yang di atas. Itu tidak memerlukan pembuatan objek setiap saat, tetapi pertama kali * menghasilkan instance saat digunakan, yang meningkatkan efisiensi! * @return */ public static singleton2 getInstance () {if (instance == null) instance = singleton2 baru (); instance return; }}Berikut ini adalah masalah multi-threading utama. Dalam singleton malas, tidak ada masalah dengan threading tunggal, tetapi ketika multi-threading, mungkin ada dua atau lebih singletion2.
Misalnya: Ketika Thread 1 menilai instance itu == NULL adalah benar, ketika memindai operasi baru, sebelum melakukan operasi baru dan setelah melakukan operasi baru, Thread 2 hanya melakukan operasi penilaian, dan instance masih nol. Oleh karena itu, Thread 2 juga akan melakukan operasi baru. Dan seterusnya, di bawah konkurensi tinggi, mungkin ada dua atau lebih contoh singletion2. Jelas, ini salah.
Karena itu, ubah kode sebagai berikut:
kelas publik singleton3 {private static singleton3 instance = null; /*** // *** Metode ini ditingkatkan dibandingkan dengan yang di atas. Itu tidak memerlukan objek yang akan dihasilkan setiap waktu, tetapi pertama kali * menghasilkan contoh saat digunakan, yang meningkatkan efisiensi! * Untuk menghindari kesalahan dalam multi-threading, bendera sinkronisasi ditambahkan * @return */ public static sinkronisasi singleton3 getInstance () {if (instance == null) instance = singleton3 baru (); instance return; }}Tapi ini menciptakan masalah lain. Metode disinkronkan setiap kali contoh diambil. Jelas, kinerjanya sangat terpengaruh, jadi terus ubah kode sebagai berikut:
volatil, ganti sinkronisasi dengan biaya lebih rendah
Mengapa volatile lebih murah daripada sinkronisasi?
Biaya sinkronisasi terutama ditentukan oleh jangkauan cakupannya. Jika kisaran cakupan sinkronisasi dapat dikurangi, kinerja program dapat sangat ditingkatkan.
Cakupan volatile hanya pada level variabel. Oleh karena itu, biaya sinkronisasi sangat rendah.
Apa prinsip volatile?
Semantik volatile sebenarnya adalah untuk memberi tahu prosesor agar tidak menempatkan saya dalam memori kerja, tolong operasi saya langsung di memori utama. (Lihat model memori Java untuk memori yang berfungsi untuk detailnya)
Oleh karena itu, ketika multi-core atau multi-threading mengakses variabel, mereka akan secara langsung mengoperasikan memori utama, yang pada dasarnya mencapai berbagi variabel.
Apa keuntungan dari volatile?
1. Throughput program yang lebih besar
2. Kode Kurang Untuk Mengimplementasikan Multi-Threading
3. Program ini memiliki skalabilitas yang lebih baik
4. Lebih mudah untuk dipahami, dan tidak perlu biaya belajar yang terlalu tinggi.
Apa kerugian dari volatile?
1. Rentan terhadap masalah
2. Sulit untuk dirancang
Volatile menggunakan JDK membutuhkan versi 1.5 ke atas.
Kode yang ditingkatkan adalah sebagai berikut (juga disebut kunci ganda):
kelas publik singleton4 {instance private static volatile singleton4; /*** // *** Penguncian ganda untuk mencapai aplikasi multi-threading dan optimasi kinerja* @return*/public static singleton4 getInstance () {if (instance == null) {disinkronkan (singleton4.class) {// 1 if (instance == null)/2 instance = singleton4 baru (); // 3}} instance return; }}