تنفيذ وضع Singleton (5 أنواع)
شائع الاستخدام:
نمط الجائع (مؤشر ترابط آمن ، كفاءة مكالمة عالية ، ولكن لا يمكن تحميلها بطريقة متأخرة)
النمط الكسول (الخيط آمن ، كفاءة مكالمة منخفضة ، يمكن تحميلها في التأخير)
آخر:
نوع قفل الكشف المزدوج (بسبب النموذج الداخلي الأساسي لـ JVM ، ستكون هناك مشاكل في بعض الأحيان ولن يتم بناؤها واستخدامها)
فئة داخلية ثابتة (آمن الخيط ، كفاءة مكالمة عالية ، ولكن يمكن تحميلها بطريقة متأخرة)
تعداد المفردات (آمنة الخيط ، كفاءة مكالمة عالية ، ولا يمكن تحميلها في تأخير)
المدونة المحددة للفرد المفرد للرجل الجائع هي كما يلي:
حزمة com.lcx.mode ؛ /** * * مفردة من الناس الجياع. بغض النظر عما إذا كان هذا الكائن يستخدم في المستقبل أم لا ، فإننا ننشئ مثيلًا لهذا الكائن من البداية. * عند الحاجة ، نعيد كائن المثيل الذي تم إنشاؤه ، لذلك نحن جائعون نسبيًا ، لذلك يسمى هذا المفرد من الناس الجياع. * Author QQ1013985957 * */ Class Class Singletonhanger {مثيل Singletonhanger Final Static Static = New Singletonhanger () ؛ Singletonhanger الخاص () {} Singletonhanger GetInstance () {Return estance ؛ }} /*** Lazy Han-style Singleton ، عندما تكون هناك حاجة إلى كائن Singleton ، فإنه سيقوم بإنشاء كائن Singleton الوحيد ، ويطلق عليه مرة أخرى لاحقًا ، ويتم تهيئة كائن Singleton الذي تم إنشاؤه أيضًا ، لذلك يتم تهيئة Singleton العضو الثابت إلى Null ، ويخلقه عند الحصول على Singleton ، لذلك يطلق عليه اسم Lazy Han-Style. * Author qq1013985957 * */ class singletonlazy {private static singletonlazy مثيل = null ؛ خاص singletonlazy () {} /*** لا يمكن استخدام Singleton التي تم تنفيذها بواسطة هذه الطريقة في سلسلة رسائل متعددة. يمكن لخطوط متعددة إدخال الطريقة إذا كان في نفس الوقت ، مما سيؤدي إلى إنشاء كائنات مفردة متعددة. * return */ public static singletonlazy getInstance1 () {if (مثيل == null) {مثيل = جديد singletonlazy () ؛ } مثيل الإرجاع ؛ } /*** سيفكر الجميع في التزامن. يمكن للطريقة المتزامنة تنفيذ Singleton متعدد الخيوط* ومع ذلك ، فإن هذه الطريقة ليست مرغوبة وتؤثر بشكل خطير على الأداء. نظرًا لأنه يجب فحص الطريقة في كل مرة تحصل فيها على Singleton ، يمكنك فقط استخدام كتلة الكود المتزامن لتحقيق المزامنة. * @return */ public static singletonlazy getInstance2 () {if (مثيل == null) {مثيل = جديد singletonlazy () ؛ } مثيل الإرجاع ؛ } /*** استخدم كتلة التعليمات البرمجية المتزامنة لاستخدام كتلة الكود المتزامن في طريقة IF لتحديد ما إذا كان هناك Singleton ، وتحقق مرة أخرى في كتلة الكود المتزامن ما إذا كان قد تم إنشاء المفرد. * هذه هي طريقة القفل المزدوج على الإنترنت * @RETURN */ public static singletonlazy getInstance3 () {if (مثيل == null) {synchronized (singletonlazy.class) {if (مثيل == null) {extal = new singletonlazy () ؛ }}} مثيل الإرجاع ؛ }} /*** استخدم التعدادات لتنفيذ وضع Singleton ، والتي هي أيضًا الطريقة الموصى بها للاستخدام في مثيل Java* الفعال وفقًا للوضع المحدد. بالنسبة للطلاب الذين ليسوا على دراية بالتعداد ، يمكنك الرجوع إلى الفهم الأولي لفئة تعداد Java الخاصة بي. * فوائدها: إنها أكثر إيجازًا وتوفر آلية التسلسل مجانًا ، ومنعًا تمامًا لتكوين إنشاءات متعددة ، حتى في مواجهة التسلسل المعقد والانعكاس. * Author qq1013985957 * */ enum singletionenum {singletionenum ("singleton enum") ؛ سلسلة خاصة singletionenum الخاص (String str) {this.setstr (str) ؛ } السلسلة العامة getstr () {return str ؛ } public void setStr (String str) {this.str = str ؛ }} لا يتم اختبار نمط المفرد أعلاه. يمكنك اختباره لتحديد ما إذا كان رمز Hashcode للكائن متسقًا لتحديد ما إذا كان هو نفس الكائن.
لا يمكن للطرق الشريرة والكسل أن تمنع الانعكاس من تنفيذ مثيلات متعددة. من خلال الانعكاس ، يمكن لإنشاء طريقة يمكن الوصول إليها. يمكنك تعديل المُنشئ لرمي استثناء عندما يُطلب منه إنشاء مثيل ثانية.
في الواقع ، هذا لا يمكن أن يضمن singleton. بعد التسلسل ، يمكن لفرط التسلسل إنشاء مثيل جديد ، وإضافة طريقة ReadResolve () إلى فئة Singleton لمنعها.
رمز Singleton الكسول على غرار الرجل هو كما يلي:
حزمة com.lcx.mode ؛ استيراد java.io.file ؛ استيراد java.io.fileInputStream ؛ استيراد java.io.fileOutputStream ؛ استيراد java.io.objectinputStream ؛ استيراد java.io.objectOutputStream ؛ استيراد java.io.serializable ؛ استيراد java.lang.reflect.constructor ؛ استيراد java.lang.reflect.invocationTargetException ؛ /*** يتم إنشاء Singletons Lazy Man-Style عند الحاجة إلى كائن Singleton. عندما تكون هناك حاجة إلى كائن Singleton ، سيتم استدعاؤه مرة أخرى لاحقًا. يعد كائن Singleton الذي تم إرجاعه أيضًا أول كائن Singleton الذي تم إنشاؤه* يهيئ العضو الثابت إلى Null ، ويخلقه عند الحصول على Singleton ، لذلك يطلق عليه Lazy Man-Style. * Author qq1013985957 * */ الطبقة العامة ينفذ Singleton قابلة للتسلسل {/ ** * *// private Static Final Long SerialVersionuid = -5271537207137321645L ؛ مثيل Singleton ثابت خاص = فارغ ؛ int static int i = 1 ؛ Singleton الخاص () { / *** منع هجمات الانعكاس ، فقط قم بالتشغيل واستدعاء المُنشئ مرة واحدة ، ورمي الاستثناء في المرة الثانية* / if (i == 1) {i ++ ؛ } آخر {رمي RunTimeException جديد ("لا يمكن استدعاء مُنشئ مرة واحدة إلا مرة واحدة") ؛ } System.out.println ("Call Singleton's Private") ؛ } /*** استخدم كتلة التعليمات البرمجية المتزامنة لاستخدام كتلة الكود المتزامن في طريقة IF لتحديد ما إذا كان هناك Singleton ، وتحقق مرة أخرى في كتلة الكود المتزامن ما إذا كان قد تم إنشاء المفرد. * هذا هو ما يطلق عليه الإنترنت طريقة قفل التحقق المزدوج * @RETURN */ Public Static Synchronized Singleton getInstance () {if (مثيل == null) {synchronized (singleton.class) {if (exate == null) {مثيل = new singleton () ؛ }} مثيل الإرجاع ؛ } /*** منع desequence من توليد كائنات مفردة جديدة. هذا ما يقال في كتاب جافا الفعالة. يمكن منع هذه الطريقة. لا أفهم التفاصيل المحددة * @return */ كائن خاص ReadResolve () {return evalue ؛ } public static void main (string [] args) يلقي الاستثناء {test1 () ؛ Test2 () ؛ } / *** اختبار desequence لا يزال وضع singleton* athrows استثناء* / public static void test2 () يلقي الاستثناء {singleton s = singleton.getinstance () ؛ ObjectOutputStream ObjectOutPutStream = new ObjectOutputStream (FileOutputStream جديد (ملف جديد ("E: //singleton.txt"))) ؛ ObjectOutputStream.writeObject (s) ؛ ObjectInputStream ObjectInputStream = new ObjectInputStream (FileInputStream جديد (ملف جديد ("E: //singleton.txt")))) ؛ Object readObject = ObjectInputStream.ReadObject () ؛ Singleton S1 = (Singleton) ReadObject ؛ System.out.println ("S.HashCode ():"+S.HashCode ()+"، s1.hashCode ():"+s1.hashcode ()) ؛ ObjectOutputStream.flush () ؛ ObjectOutputStream.close () ؛ ObjectInputStream.close () ؛ ObjectInputStream.close () ؛ } / *** اختبار الانعكاس هجوم* Throws استثناء* / public static void test1 () {singleton s = singleton.getInstance () ؛ الفئة C = singleton.class ؛ مُنشئ الخصوصية ؛ حاول {privateconstructor = c.getDeclaredConstructor () ؛ privateconstructor.setAccible (true) ؛ privateconstructor.newinstance () ؛ } catch (استثناء e) {E.PrintStackTrace () ؛ }}}تحقق من نتائج هجوم الانعكاس:
إذا لم تتم إضافة نتيجة طريقة ReadResolve:
نتيجة إضافة طريقة ReadResolve:
شكرا لك على القراءة ، آمل أن تساعدك. شكرا لك على دعمك لهذا الموقع!