จุดประสงค์ของรูปแบบ Singleton คือเพื่อให้แน่ใจว่าชั้นเรียนมีเพียงหนึ่งอินสแตนซ์และยังให้จุดเชื่อมต่อทั่วโลกสำหรับมัน เพื่อป้องกันไม่ให้คนงานคนอื่น ๆ จากการสร้างอินสแตนซ์ชั้นเรียนของเรา
คุณสามารถสร้างตัวสร้างที่ไม่ซ้ำกันสำหรับคลาสนี้และตั้งค่าที่มองเห็นได้ของตัวสร้างเป็นส่วนตัว เป็นที่น่าสังเกตว่าถ้าเราสร้างตัวสร้างที่ไม่ใช่เอกชนอื่น ๆ หรือเราไม่ได้กล่าวถึงชั้นเรียนเลย
สำหรับตัวสร้างจากนั้นคนอื่น ๆ ก็ยังสามารถยกตัวอย่างชั้นเรียนของเราได้ หากเราไม่ต้องการสร้างวัตถุซิงเกิลล่วงหน้าเราสามารถรอได้จนถึงครั้งแรกที่เราใช้วัตถุซิงเกิลนั่นคือนั่นคือ
การเริ่มต้นล่าช้า มีเหตุผลสองประการสำหรับการเริ่มต้นการเริ่มต้นของวัตถุซิงเกิลตัน:
1. บางทีในเวลาเริ่มต้นแบบคงที่คุณไม่มีข้อมูลเพียงพอเกี่ยวกับวิธีการเริ่มต้นวัตถุซิงเกิล
2. จุดประสงค์ในการเลือกการเริ่มต้นความล่าช้าเดี่ยวอาจรอทรัพยากรเช่นการเชื่อมต่อฐานข้อมูลโดยเฉพาะอย่างยิ่งในแอพพลิเคชั่นที่ไม่จำเป็นต้องใช้ซิงเกิลตันในเซสชันที่เฉพาะเจาะจง
หาก Singleton เริ่มต้นในสภาพแวดล้อมแบบมัลติเธรดเราจะต้องระมัดระวังในการป้องกันหลายเธรดจากการเริ่มต้นในเวลาเดียวกัน
โดยปกติรูปแบบ Singleton จะถูกสร้างขึ้นในภาษา Java:
Lazy Way: หมายถึงอินสแตนซ์ Singleton ทั่วโลกที่ถูกสร้างขึ้นเมื่อใช้เป็นครั้งแรก การเริ่มต้นล่าช้า
วิธีการของ Hungry Man: หมายถึงอินสแตนซ์เดียวทั่วโลกที่ถูกสร้างขึ้นระหว่างการโหลดชั้นเรียน การเริ่มต้นอย่างเร่งด่วน
1. หิวจีนซิงเกิลตัน
คลาสสาธารณะ Singleton1 {Private Singleton1 () {} // กำหนดอินสแตนซ์ของคุณเองภายใน // โปรดทราบว่านี่เป็นส่วนตัว อินสแตนซ์แบบคงที่ส่วนตัว Singleton1 = New Singleton1 (); /** * // ** * นี่คือวิธีการคงที่สำหรับการเข้าถึงภายนอกไปยังคลาสนี้ซึ่งสามารถเข้าถึงได้โดยตรง * @return */สาธารณะคงที่ Singleton1 GetInstance () {return Instance; -2. คลาส Lazy Singleton
Public Class Singleton2 {Instance Static Singleton2 ส่วนตัว = NULL; /*** // *** วิธีนี้ได้รับการปรับปรุงเมื่อเทียบกับข้างต้น ไม่จำเป็นต้องมีการสร้างวัตถุทุกครั้ง แต่ครั้งแรก * สร้างอินสแตนซ์เมื่อใช้ซึ่งช่วยปรับปรุงประสิทธิภาพ! * @return */ สาธารณะคงที่ singleton2 getInstance () {ถ้า (อินสแตนซ์ == null) อินสแตนซ์ = ใหม่ singleton2 (); อินสแตนซ์กลับ; -ต่อไปนี้เป็นปัญหามัลติเธรดหลัก ใน Singletons ที่ขี้เกียจไม่มีปัญหากับการทำเกลียวเดี่ยว แต่เมื่อมัลติเธรดอาจมีสองครั้งหรือมากกว่านั้น
ตัวอย่างเช่น: เมื่อเธรด 1 ตัดสินว่าอินสแตนซ์ == null เป็นจริงเมื่อสแกนการดำเนินการใหม่ก่อนที่จะดำเนินการใหม่และหลังจากดำเนินการใหม่เธรด 2 เพียงดำเนินการตัดสินและอินสแตนซ์ยังคงเป็นโมฆะ ดังนั้นเธรด 2 จะดำเนินการใหม่ และอื่น ๆ ภายใต้การพร้อมกันที่สูงอาจมีสองกรณีของ singletion2 เห็นได้ชัดว่านี่ไม่ถูกต้อง
ดังนั้นเปลี่ยนรหัสดังนี้:
คลาสสาธารณะ Singleton3 {อินสแตนซ์แบบคงที่ส่วนตัว Singleton3 = null; /*** // *** วิธีนี้ได้รับการปรับปรุงเมื่อเทียบกับข้างต้น ไม่จำเป็นต้องสร้างวัตถุทุกครั้ง แต่ครั้งแรก * สร้างอินสแตนซ์เมื่อใช้ซึ่งช่วยปรับปรุงประสิทธิภาพ! * เพื่อหลีกเลี่ยงข้อผิดพลาดในมัลติเธรดธงการซิงโครไนซ์ถูกเพิ่ม * @return */ สาธารณะแบบคงที่แบบคงที่ Singleton3 getInstance () {ถ้า (อินสแตนซ์ == null) อินสแตนซ์ = new Singleton3 (); อินสแตนซ์กลับ; -แต่สิ่งนี้สร้างปัญหาอื่น วิธีการจะซิงโครไนซ์ทุกครั้งที่มีการดึงอินสแตนซ์ เห็นได้ชัดว่าประสิทธิภาพได้รับผลกระทบอย่างมากดังนั้นจึงเปลี่ยนรหัสดังต่อไปนี้:
ผันผวนเปลี่ยนการซิงโครไนซ์ด้วยต้นทุนที่ต่ำกว่า
เหตุใดจึงมีความผันผวนถูกกว่าการซิงโครไนซ์?
ค่าใช้จ่ายในการซิงโครไนซ์ส่วนใหญ่จะถูกกำหนดโดยช่วงความครอบคลุม หากช่วงความครอบคลุมของการซิงโครไนซ์สามารถลดลงประสิทธิภาพของโปรแกรมสามารถปรับปรุงได้อย่างมาก
ความครอบคลุมของความผันผวนอยู่ที่ระดับตัวแปรเท่านั้น ดังนั้นต้นทุนการซิงโครไนซ์จึงต่ำมาก
หลักการของความผันผวนคืออะไร?
ความหมายของความผันผวนจริง ๆ แล้วจะบอกโปรเซสเซอร์ว่าอย่าทำให้ฉันอยู่ในหน่วยความจำที่ทำงานได้โปรดใช้งานฉันโดยตรงในหน่วยความจำหลัก (ดูรุ่นหน่วยความจำ Java สำหรับหน่วยความจำที่ใช้งานได้สำหรับรายละเอียด)
ดังนั้นเมื่อมัลติคอร์หรือมัลติเธรดเข้าถึงตัวแปรพวกเขาจะใช้งานหน่วยความจำหลักโดยตรงซึ่งบรรลุการแบ่งปันตัวแปร
อะไรคือข้อดีของความผันผวน?
1. ปริมาณงานที่ใหญ่กว่าของโปรแกรม
2. รหัสน้อยกว่าที่จะใช้การเธรดมัลติเธรด
3. โปรแกรมมีความยืดหยุ่นที่ดีขึ้น
4. มันง่ายกว่าที่จะเข้าใจและไม่จำเป็นต้องมีค่าใช้จ่ายในการเรียนรู้สูงเกินไป
ข้อเสียของความผันผวนคืออะไร?
1. มีแนวโน้มที่จะเกิดปัญหา
2. มันยากที่จะออกแบบ
ความผันผวนใช้ JDK ต้องการเวอร์ชัน 1.5 ขึ้นไป
รหัสที่ได้รับการปรับปรุงมีดังนี้ (เรียกอีกอย่างว่า Double Lock):
Public Class Singleton4 {อินสแตนซ์แบบคงที่แบบคงที่ส่วนตัว Singleton4; /*** // *** การล็อคสองครั้งเพื่อให้ได้แอปพลิเคชันแบบมัลติเธรดและการเพิ่มประสิทธิภาพประสิทธิภาพ* @return*/สาธารณะคงที่ singleton4 getInstance () {ถ้า (อินสแตนซ์ == null) {ซิงโครไนซ์ (singleton4.class) {// 1 ถ้า (อินสแตนซ์ == null) // 2 อินสแตนซ์ // 3}} ส่งคืนอินสแตนซ์; -