รูปแบบซิงเกิลตันมีลักษณะดังต่อไปนี้:
1. คลาสซิงเกิลตันสามารถมีได้เพียงอินสแตนซ์เดียวเท่านั้น
2. คลาสซิงเกิลตันต้องสร้างอินสแตนซ์เฉพาะของตัวเอง
3. คลาสซิงเกิลตันต้องจัดเตรียมอินสแตนซ์นี้ให้กับออบเจ็กต์อื่นทั้งหมด
รูปแบบซิงเกิลตันช่วยให้แน่ใจว่ามีเพียงอินสแตนซ์เดียวของคลาส และจะสร้างอินสแตนซ์ให้กับตัวเองและจัดเตรียมอินสแตนซ์นี้ให้กับทั้งระบบ ในระบบคอมพิวเตอร์ เธรดพูล แคช วัตถุบันทึก กล่องโต้ตอบ เครื่องพิมพ์ และวัตถุไดรเวอร์การ์ดแสดงผล มักได้รับการออกแบบให้เป็นซิงเกิลตัน แอปพลิเคชันเหล่านี้ล้วนมีฟังก์ชันการทำงานของผู้จัดการทรัพยากรไม่มากก็น้อย คอมพิวเตอร์แต่ละเครื่องสามารถมีเครื่องพิมพ์ได้หลายเครื่อง แต่จะมี Printer Spooler ได้เพียงเครื่องเดียวเท่านั้น เพื่อป้องกันไม่ให้งานพิมพ์สองงานถูกส่งออกไปยังเครื่องพิมพ์ในเวลาเดียวกัน คอมพิวเตอร์แต่ละเครื่องสามารถมีพอร์ตการสื่อสารได้หลายพอร์ต และระบบควรจัดการพอร์ตการสื่อสารเหล่านี้จากส่วนกลาง เพื่อป้องกันไม่ให้พอร์ตการสื่อสารหนึ่งพอร์ตถูกเรียกโดยคำขอสองรายการในเวลาเดียวกัน กล่าวโดยสรุป วัตถุประสงค์ของการเลือกโหมดซิงเกิลตันคือเพื่อหลีกเลี่ยงสถานะที่ไม่สอดคล้องกันและหลีกเลี่ยงนโยบายระยะยาว
ก่อนอื่น มาดูการใช้งานซิงเกิลตันแบบคลาสสิกกันก่อน
คัดลอกรหัสรหัสดังต่อไปนี้:
คลาสสาธารณะซิงเกิลตัน {
ส่วนตัว Singleton แบบคงที่ UniqueInstance = null;
ซิงเกิลตันส่วนตัว () {
// มีอยู่เพื่อเอาชนะการสร้างอินสแตนซ์เท่านั้น
-
สาธารณะคงที่ Singleton getInstance () { ถ้า (uniqueInstance == null) {
UniqueInstance = ซิงเกิลตันใหม่ ();
-
กลับอินสแตนซ์ที่ไม่ซ้ำกัน;
-
// วิธีอื่นๆ...
-
Singleton หลีกเลี่ยงไม่ให้คลาสถูกสร้างอินสแตนซ์จากภายนอกโดยการจำกัดวิธีสร้างให้เป็นส่วนตัว ภายในขอบเขตของเครื่องเสมือนเดียวกัน อินสแตนซ์เดียวของ Singleton เท่านั้นที่สามารถเข้าถึงได้ผ่านเมธอด getInstance() เท่านั้น (ในความเป็นจริง เป็นไปได้ที่จะสร้างอินสแตนซ์คลาสด้วยคอนสตรัคเตอร์ส่วนตัวผ่านกลไกการสะท้อนของ Java ซึ่งโดยพื้นฐานแล้วจะทำให้การใช้งาน Java singleton ทั้งหมดเป็นโมฆะ ปัญหานี้จะไม่กล่าวถึงที่นี่ สมมติว่าไม่มีกลไกการสะท้อนกลับ .)
อย่างไรก็ตาม การใช้งานข้างต้นไม่ได้คำนึงถึงปัญหาด้านความปลอดภัยของเธรด สิ่งที่เรียกว่าความปลอดภัยของเธรดหมายถึง: หากมีหลายเธรดที่ทำงานพร้อมกันในกระบวนการที่มีโค้ดของคุณอยู่ เธรดเหล่านี้อาจเรียกใช้โค้ดนี้ในเวลาเดียวกัน หากผลลัพธ์ของการรันแต่ละครั้งเหมือนกับผลลัพธ์ของการรันแบบเธรดเดียวและค่าของตัวแปรอื่น ๆ เหมือนกับที่คาดไว้ แสดงว่าเป็นเธรดที่ปลอดภัย กล่าวอีกนัยหนึ่ง: อินเทอร์เฟซที่คลาสหรือโปรแกรมมอบให้นั้นเป็นการดำเนินการแบบอะตอมมิกสำหรับเธรด หรือการสลับระหว่างเธรดหลายตัวจะไม่ทำให้เกิดความคลุมเครือในผลลัพธ์การดำเนินการของอินเทอร์เฟซ ซึ่งหมายความว่าเราไม่จำเป็นต้องพิจารณาปัญหาการซิงโครไนซ์ แน่นอนว่าการใช้งานข้างต้นไม่เป็นไปตามข้อกำหนดด้านความปลอดภัยของเธรด และอินสแตนซ์ Singleton หลายรายการมีแนวโน้มที่จะปรากฏในสภาพแวดล้อมพร้อมกัน
คัดลอกรหัสรหัสดังต่อไปนี้:
//คลาสซิงเกิลตันสไตล์หิว มันถูกสร้างอินสแตนซ์ด้วยตัวเองเมื่อเริ่มต้นคลาส
คลาสสาธารณะ Singleton1 {
//คอนสตรัคเตอร์เริ่มต้นส่วนตัว
ซิงเกิลตัน1() {} ส่วนตัว
//สร้างอินสแตนซ์ด้วยตัวเองแล้ว
Singleton1 สุดท้ายแบบคงที่ส่วนตัว single = new Singleton1 ();
// วิธีการโรงงานแบบคงที่
Singleton1 getInstance สาธารณะแบบคงที่ () {
กลับเดี่ยว;
-
-
//Lazy singleton class. สร้างอินสแตนซ์เมื่อถูกเรียกเป็นครั้งแรก
คลาสสาธารณะ Singleton2 {
//คอนสตรัคเตอร์เริ่มต้นส่วนตัว
ซิงเกิลตัน2() {} ส่วนตัว
//หมายเหตุ ไม่มีจุดสิ้นสุดที่นี่
Singleton2 คงที่ส่วนตัว single = null;
// วิธีการโรงงานแบบคงที่
การซิงโครไนซ์สาธารณะ Singleton2 getInstance () {
ถ้า (เดี่ยว == null) {
เดี่ยว = ใหม่ Singleton2();
-
กลับเดี่ยว;
-
-