Pola singleton memiliki ciri-ciri sebagai berikut:
1. Kelas singleton hanya dapat memiliki satu instance.
2. Kelas tunggal harus membuat instance uniknya sendiri.
3. Kelas singleton harus menyediakan instance ini ke semua objek lainnya.
Pola singleton memastikan bahwa hanya ada satu instance dari suatu kelas, dan ia membuat instance dirinya sendiri serta menyediakan instance ini ke seluruh sistem. Dalam sistem komputer, kumpulan thread, cache, objek log, kotak dialog, printer, dan objek driver kartu grafis sering kali dirancang sebagai singleton. Semua aplikasi ini kurang lebih memiliki fungsi pengelola sumber daya. Setiap komputer dapat memiliki beberapa printer, namun hanya ada satu Printer Spooler untuk mencegah dua pekerjaan pencetakan dikeluarkan ke printer pada saat yang bersamaan. Setiap komputer dapat memiliki beberapa port komunikasi, dan sistem harus mengelola port komunikasi ini secara terpusat untuk mencegah satu port komunikasi dipanggil oleh dua permintaan pada saat yang bersamaan. Singkatnya, tujuan memilih mode tunggal adalah untuk menghindari keadaan yang tidak konsisten dan menghindari kebijakan jangka panjang.
Pertama, mari kita lihat implementasi singleton klasik.
Copy kode kodenya sebagai berikut:
kelas publik Singleton {
private static Singleton UniqueInstance = null;
pribadi Singleton() {
// Ada hanya untuk mengalahkan instantiasi.
}
public static Singleton getInstance() { jika (uniqueInstance == null) {
UniqueInstance = Singleton baru();
}
kembalikan UniqueInstance;
}
// Metode lain...
}
Singleton menghindari kelas dipakai secara eksternal dengan membatasi metode konstruksi menjadi pribadi. Dalam lingkup mesin virtual yang sama, satu-satunya instance Singleton hanya dapat diakses melalui metode getInstance(). (Faktanya, dimungkinkan untuk membuat instance kelas dengan konstruktor pribadi melalui mekanisme refleksi Java, yang pada dasarnya akan membatalkan semua implementasi Java singleton. Masalah ini tidak akan dibahas di sini. Anggap saja mekanisme refleksi tidak ada. .)
Namun implementasi di atas tidak mempertimbangkan masalah keamanan thread. Yang disebut keamanan thread berarti: jika ada beberapa thread yang berjalan pada waktu yang sama dalam proses di mana kode Anda berada, thread ini dapat menjalankan kode ini pada waktu yang sama. Jika hasil setiap proses sama dengan hasil proses single-thread, dan nilai variabel lain sama seperti yang diharapkan, maka thread tersebut aman. Dengan kata lain: antarmuka yang disediakan oleh suatu kelas atau program adalah operasi atom untuk thread atau peralihan antara beberapa thread tidak akan menyebabkan ambiguitas dalam hasil eksekusi antarmuka, yang berarti kita tidak perlu mempertimbangkan masalah sinkronisasi. Jelas sekali implementasi di atas tidak memenuhi persyaratan keamanan thread, dan beberapa instance Singleton kemungkinan besar akan muncul di lingkungan bersamaan.
Copy kode kodenya sebagai berikut:
//Kelas singleton bergaya lapar. Kelas ini telah dibuat instance-nya sendiri saat kelas diinisialisasi.
kelas publik Singleton1 {
//Konstruktor default pribadi
pribadi Singleton1() {}
//Sudah dipakai sendiri
private static final Singleton1 single = new Singleton1();
//metode pabrik statis
publik statis Singleton1 getInstance() {
kembali lajang;
}
}
//Kelas singleton yang malas. Buat instance saat dipanggil untuk pertama kalinya
kelas publik Singleton2 {
//Konstruktor default pribadi
pribadi Singleton2() {}
//Catatan, tidak ada final di sini
pribadi statis Singleton2 single=null;
//metode pabrik statis
singleton2 statis tersinkronisasi publik getInstance() {
jika (tunggal == nol) {
tunggal = baru Singleton2();
}
kembali lajang;
}
}