نمط Singleton هو الأسهل في الفهم وأسهل طريقة لكود مكتوب يدويًا في نمط التصميم ، ولكن لا توجد العديد من نقاط المعرفة المعنية ، لذلك غالبًا ما يتم استخدامها كمسألة مقابلة. بشكل عام ، تتم كتابة المفردات بخمس طرق: LAZY ، جائع ، قفل فحص مزدوج ، فصول داخلية ثابتة وتعداد. من أجل تسجيل عملية التعلم ، تم تجميع العديد من أساليب كتابة Singleton المشتركة هنا.
البرونز 5: (محمّل كسول ، لكن الخيط غير آمن)
عندما سئل عن تنفيذ نمط المفرد ، فإن رد الفعل الأول للعديد من الأشخاص هو كتابة الكود التالي ، بما في ذلك نفس التعاليم في الكتب المدرسية.
الطبقة العامة Singleton {مثيل خاص ثابت Singleton ؛ خاص singleton () {} static singleton getInstance () {if (مثيل == null) {مثيل = جديد singleton () ؛ } مثيل الإرجاع ؛ }}هذا الرمز بسيط ومباشر ، ويستخدم وضع التحميل المتأخر ، لكن مؤشرات الترابط غير آمنة. قد يتسبب استدعاء طريقة getInstance () في بيئة متعددة الخيوط في إدخال سلسلة مؤشرات ترابط متعددة إلى كتلة رمز البرنامج IF.
النمط الكسول: متزامن (محمّل كسول ، آمن مؤشر ترابط ، ولكن ليس فعالًا)
لحل المشكلة أعلاه ، أسهل طريقة هي تعيين طريقة getInstance () بالكامل على المزامنة.
الطبقة العامة Singleton {مثيل خاص ثابت Singleton ؛ خاص singleton () {} static static singleton getInstance () {if (مثيل == null) {مثيل = جديد singleton () ؛ } مثيل الإرجاع ؛ }}على الرغم من أنه آمن من الخيط وتأخير التحميل ، إلا أنه غير فعال. لأنه في أي وقت لا يمكن أن يكون هناك سوى موضوع واحد يدعو إلى طريقة getInstance (). ومع ذلك ، يجب أن تكون هناك حاجة فقط للعملية المتزامنة في المكالمة الأولى ، أي عند إنشاء كائن مثيل Singleton لأول مرة. يؤدي هذا النمط إلى الوصول إلى سلسلة واحدة فقط للوصول إلى طريقة getInstance () في وقت واحد حتى بعد إنشاء Singleton ، مما قد يؤدي إلى مشاكل في الأداء المحتملة. هذا يؤدي إلى قفل فحص مزدوج.
النمط الجائع: الحقل النهائي الثابت (غير محمّل للبلدان)
هذه الطريقة بسيطة للغاية ، لأنه يتم الإعلان عن مثيل Singleton على أنه نهائي ثابت ويتم تهيئته عند تحميل الفئة في الذاكرة لأول مرة ، وبالتالي فإن إنشاء كائن مثيل آمن مؤشر ترابط (مضمون بتنفيذ JVM).
الطبقة العامة Singleton {// تهيئة مثيل Singleton Final Static الخاص = New Singleton () ؛ خاص singleton () {} Singleton GetInstance () {// singleton مع مثيل عودة المصنع الثابت ؛ }}إنه ليس وضع تحميل كسول ، وسيتم تهيئة المثيل من البداية بعد تحميل الفصل ، حتى لو لم يتصل العميل بالطريقة getInstance (). سيؤدي ذلك إلى بعض قيود الاستخدام: على سبيل المثال ، يعتمد إنشاء مثيل Singleton على المعلمات أو ملفات التكوين. قبل GetInstance () ، يجب استدعاء طريقة معينة لتعيين المعلمات عليها ، حتى لا يتم استخدام طريقة كتابة Singleton هذه. تشمل الطرق المماثلة:
الطبقة العامة Singleton {public static Final Singleton مثال = New Singleton () ؛ .قفل فحص مزدوج + متقلبة (Lazyload ، آمن الخيط ، ولكن غامضة)
نمط القفل المزدوج الذي تم فحصه هو وسيلة للقفل باستخدام كتل متزامنة. يطلق عليه المبرمجون قفل فحص مزدوج لأنه سيكون هناك مثيل اثنين من الفرق == NULL ، مرة واحدة خارج كتلة المزامنة ومرة واحدة داخل كتلة التزامن. لماذا نحتاج إلى التحقق مرة أخرى في كتلة التزامن؟ نظرًا لأن مؤشرات الترابط المتعددة قد تدخل إذا كانت خارج كتلة التزامن معًا ، إذا لم يتم إجراء التحقق الثانوي في كتلة التزامن ، سيتم إنشاء كائنات مثيل متعددة.
Singleton Singleton Public Static GetSingleton () {if (مثيل == null) {// تم فحص واحد متزامن (singleton.class) {if (مثيل == null) {// double checked مثيل = جديد singleton () ؛ }}} مثيل الإرجاع ؛}يبدو هذا الرمز مثاليًا ، لكن للأسف هو مشكلة. الشيء الرئيسي هو مثيل الجملة = New Singleton (). هذه ليست عملية ذرية. في الواقع ، هذه الجملة في JVM تفعل ما يقرب من 3 الأشياء التالية.
ومع ذلك ، هناك تحسين لإعادة ترتيب التعليمات في برنامج التحويل البرمجي JVM JIT. بمعنى آخر ، لا يمكن ضمان ترتيب الخطوتين الثانية والثالثة أعلاه ، وقد يكون أمر التنفيذ النهائي 1-2-3 أو 1-3-2. إذا كان هذا هو الأخير ، فسيتم استباقه بواسطة الموضوع 2 قبل تنفيذ 3 و 2. في هذا الوقت ، يكون المثيل بالفعل غير فائق (ولكن لم يتم تهيئته) ، لذلك سيعود مؤشر الترابط 2 إلى المثيل مباشرة ، ثم استخدامه ، ثم الإبلاغ عن خطأ بشكل طبيعي. للقيام بذلك ، نحتاج إلى إعلان متغير المثيل كما هو متقلبة.
الطبقة العامة Singleton {مثال Singleton Static Private Platile ؛ // DECRAY as flatile private singleton () {} singleton getSingleton () {if (مثيل == null) {synchronized (singleton.class) {if (exate == null) {مثيل = new singleton () ؛ }} مثيل الإرجاع ؛ }}ومع ذلك ، من المهم أن نلاحظ أنه لا تزال هناك مشاكل مع قفل التحقق المزدوج المتطاير في الإصدارات قبل Java 1.5. تم إصلاح هذه المشكلة فقط في Java 1.5 ، حتى تتمكن من استخدام متقلبة بعد ذلك.
الطبقة الداخلية الثابتة: IODH ، حامل تهيئة الطلب على الطلب
يجمع هذا النمط بين الطبقات الداخلية الثابتة لـ Java ومعرفة قفل التزامن الافتراضية متعددة الخيوط ، وينفذ بذكاء كلاً من عمليات تحميل الكمون وسلامة الخيط.
الطبقة العامة Singleton {private Singleton () {} private static class LazyHolder {private Static Final Singleton extreal = new Singleton () ؛ } Singleton Singleton GetInstance () {// من Wikipedia Return Lazyholder.instance ؛ }}الطبقة الداخلية الثابتة تعادل الجزء الثابت من الطبقة الخارجية. لا تعتمد كائناته على كائنات الفئة الخارجية ، بحيث يمكن إنشاؤها مباشرة. لن يتم استنساخ الطبقات الداخلية الثابتة إلا عند استخدامها لأول مرة.
قفل التزامن الافتراضي متعدد مؤشرات الترابط
كما نعلم جميعًا ، في التطوير متعدد الخيوط ، من أجل حل مشكلة التزامن ، فإنه يتم استخدامه بشكل أساسي لإضافة Mutexes للتحكم في المزامنة. ولكن في بعض الحالات ، يقوم JVM بالفعل بتنفيذ التزامن من أجلك ، وفي هذه الحالات ، لا توجد حاجة لإجراء التحكم في المزامنة يدويًا. وتشمل هذه المواقف :
1. عند تهيئة البيانات بواسطة مُعمى ثابت (التهيئة على حقل ثابت أو في كتلة {} ثابتة)
2. عند الوصول إلى الحقل النهائي
3. عند إنشاء كائن قبل إنشاء مؤشر ترابط
4. عندما يتمكن مؤشر الترابط من رؤية الكائن الذي سيتم معالجته
التعداد
بدءًا من Java 1.5 ، ما عليك سوى كتابة نوع التعداد الذي يحتوي على عنصر واحد:
التعداد العام المفرد {مثيل ؛}تشبه هذه الطريقة بشكل وظيفي طريقة المجال العام ، ولكنها أكثر إيجازًا وتوفر آلية التسلسل مجانًا ، مما يمنع تمامًا مثيلًا متعدد ، حتى عند مواجهة التسلسل أو التسلسل المعقدة أو الانعكاس. على الرغم من أن هذا النهج لم يتم اعتماده على نطاق واسع ، إلا أن أنواع التعداد للعناصر الفردية أصبحت أفضل طريقة لتنفيذ Singleton.
------------------------------------------------------------------------------------------------------------------------------------
1. ما هي تفاصيل النهائي الثابت
2. هل تهيئة المهمة في الحقل الثابت في التسلسل وكتلة الكود الثابت؟
3. كيف تكتب نمط المفرد للدروس الداخلية الثابتة
4. هل الأمثلة في تحليل نمط تصميم Java EE والتطبيق لها بالفعل تأثير كسول؟
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون محتوى هذه المقالة من بعض المساعدة في دراسة أو عمل الجميع. آمل أيضًا دعم wulin.com أكثر!