Pola tunggal adalah salah satu dari 23 pola desain. Ini adalah pola desain yang relatif sederhana. Tujuannya adalah untuk mengembalikan objek yang sama tidak peduli berapa kali dipanggil.
Ini dibagi menjadi dua struktur, satu adalah gaya orang malas dan yang lainnya adalah gaya orang lapar. Masing-masing memiliki kelebihan dan kekurangannya masing-masing. Mari kita mulai dengan gaya orang lapar.
kelas publik Tunggal { privat statis Tunggal tunggal = Single pribadi(); { } publik Tunggal getInstance() { kembali tunggal; } }
Dapat dilihat dari program di atas bahwa meskipun tujuan kita memuat objek yang sama telah tercapai, objek tunggal akan dibuat saat program dimuat. Ketika kelas ini memiliki beberapa metode seperti itu, kita tidak boleh menggunakannya pada objek ini akan menyebabkan pemborosan memori. Maka muncullah pola singleton malas. Kodenya adalah sebagai berikut:
kelas publik Tunggal { pribadi statis Tunggal = nol pribadi () {} publik Tunggal getInstance() { if(tunggal==null){ tunggal = Tunggal baru();
Dengan cara ini, objek tersebut akan menjadi baru hanya ketika kita benar-benar memanggilnya, namun ada masalah dengan ini.
Ketika potongan kode kedua di atas dipanggil oleh dua utas saat dimuat untuk pertama kalinya, dua objek berbeda akan dihasilkan, sehingga utas tersebut tidak aman. Saat ini, Anda akan berpikir untuk menambahkan Kunci, kode setelah mengunci adalah sebagai berikut:
public class Single { private static Single = null private Single() { } public disinkronkan Single getInstance() { if (single == null) { single = new Single();
Ini memang mencapai keamanan thread, tetapi ketika metode penguncian perlu melakukan banyak hal, pemanggilan metode ini akan memakan waktu lama, yang berakibat fatal bagi server, karena jika thread terus memanggil metode ini, Tidak ada cara untuk menyesuaikan thread lain, dan server akan diblokir. Maka kode yang ditingkatkan adalah sebagai berikut:
public class Single { priate static Single single = private Single() {} public Single getInstance() { if (single == null) { disinkronkan (Single.class) { single = new Single(); } }
Setelah mengamati dengan cermat, saya menemukan bahwa tidak ada kunci dengan cara ini. Ketika dua utas tiba di metode getInstance() jika penilaian untuk pertama kalinya, salah satunya harus diblokir. Setelah yang lain menyelesaikan eksekusi, utas yang diblokir akan diblokir tidak lagi Untuk menentukan apakah kosong, sebuah objek akan tetap dibuat. Dengan cara ini, beberapa objek akan dihasilkan, dan kemudian diupgrade.
public class Single { private static Single single = private Single() { } public Single getInstance() { if (single == null) { disinkronkan (Single.class) { if (single == null) { single = Single baru; (); } } } kembalikan tunggal;
Dengan cara ini masalah di atas tidak akan terjadi dan hanya akan dikunci satu kali, karena ketika metode dijalankan untuk kedua kalinya, penilaian if akan dilewati dan single akan langsung dikembalikan , dan efisiensi eksekusi akan sangat tinggi.
Namun demikian, masih terdapat masalah, karena kita tidak dapat memastikan apakah objek tersebut diberi nilai di memori terlebih dahulu atau objek tersebut dibuat terlebih dahulu, sehingga program kedua mungkin mendapatkan objek yang setengah diinisialisasi di jdk1 , kita dapat menggunakan kata kunci volatil untuk menghindari situasi ini. Kodenya adalah sebagai berikut:
public class Single { private static volatil Single single = private Single() { } public Single getInstance() { if (single == null) { disinkronkan (Single.class) { if (single == null) { single = baru; Tunggal(); } } } kembalikan tunggal;
Tapi situasi ini jarang digunakan. Saya di sini hanya untuk belajar, hehe