يوضح التعليمة البرمجية التالية كيفية مزامنة أساليب فئة معينة:
انسخ رمز الكود كما يلي:
الحزمة الأسطورية؛
الطبقة العامة SyncThread تمتد الموضوع
{
مزامنة سلسلة ثابتة خاصة = ""؛
نوع سلسلة خاصة = ""؛
طريقة الفراغ الثابت الخاص (سلسلة)
{
متزامن (متزامن)
{
مزامنة = ق؛
System.out.println(s);
بينما (صحيح)؛
}
}
طريقة الفراغ العام 1 ()
{
طريقة("method1");
}
الفراغ العام الثابت staticMethod1()
{
طريقة("staticMethod1");
}
تشغيل الفراغ العام ()
{
إذا (methodType.equals("static"))
staticMethod1();
وإلا إذا (methodType.equals("nonstatic"))
way1();
}
SyncThread العام (نوع طريقة السلسلة)
{
this.methodType =methodType;
}
يلقي الفراغ الرئيسي العام (String[] args) استثناءً
{
SyncThread Sample1 = new SyncThread("nonstatic");
SyncThread Sample2 = new SyncThread("static");
Sample1.start();
Sample2.start();
}
}
نتائج التشغيل هي كما يلي:
انسخ رمز الكود كما يلي:
طريقة1
staticMethod1
قد يفاجأ العديد من القراء برؤية نتائج التشغيل المذكورة أعلاه. في الكود أعلاه، تستخدم الطريقتان Method1 وstaticMethod1 مزامنة متغير السلسلة الثابتة للمزامنة. يمكن تنفيذ إحدى هاتين الطريقتين فقط في نفس الوقت، وستقوم كلتا الطريقتين بتنفيذ بيان الحلقة اللانهائية في السطر 014. لذلك، يمكن أن تكون نتيجة الإخراج واحدة فقط من الطريقة 1 والطريقة الثابتة 1. لكن هذا البرنامج يقوم بإخراج كلا السلسلتين.
والسبب في هذه النتيجة بسيط للغاية، سنعرفه من خلال النظر إلى السطر 012. وتبين أن قيمة المزامنة قد تغيرت في هذا السطر. أريد هنا أن أتحدث عن نوع السلسلة في Java. يختلف نوع السلسلة عن الأنواع المعقدة الأخرى في Java. عند استخدام متغير نوع السلسلة، طالما قمت بتعيين قيمة للمتغير مرة واحدة، ستقوم Java بإنشاء مثيل جديد من نوع السلسلة. كما هو موضح في الكود التالي :
انسخ رمز الكود كما يلي:
سلسلة ق = "مرحبا"؛
System.out.println(s.hashCode());
س = "العالم";
System.out.println(s.hashCode());
في الكود أعلاه. تختلف قيم hashCode للقيم الأولى والقيم المعاد تعيينها. نظرًا لأن إنشاء مثيل لفئة السلسلة لا يتطلب استخدام جديد، فعند مزامنة متغير نوع السلسلة، احرص على عدم تعيين قيمة لهذا المتغير، وإلا فلن تتم مزامنة المتغير.
نظرًا لأنه تم إنشاء مثيل جديد للمزامنة في السطر 012، بافتراض تنفيذ الطريقة 1 أولاً، عندما تقوم الطريقة 1 بتنفيذ التعليمات البرمجية في السطر 013، لم تعد قيمة المزامنة هي القيمة الأصلية، ولا تزال الطريقة 1 تقفل متغير المزامنة . في هذا الوقت، يتم تنفيذ staticMethod1 على المزامنة (المزامنة). لم تعد المزامنة التي سيتم قفلها في الطريقة staticMethod1 والمزامنة المقفلة بواسطة الطريقة 1 هي نفسها، لذلك تم تدمير مزامنة الطريقتين.
حل المشكلة المذكورة أعلاه هو بالطبع إزالة السطر 012. تمت إضافة هذا السطر إلى هذا المثال فقط لتوضيح أنه عند استخدام متغيرات الفئة لمزامنة الأساليب، إذا تم تغيير قيمة متغير المزامنة في الكتلة المتزامنة، فسيتم تدمير المزامنة بين الأساليب. لتجنب هذا الموقف تمامًا، يمكنك استخدام الكلمة الأساسية النهائية عند تحديد متغيرات المزامنة. على سبيل المثال يمكن تغيير السطر 005 في البرنامج أعلاه إلى الشكل التالي:
انسخ رمز الكود كما يلي:
مزامنة السلسلة الثابتة النهائية الخاصة = ""؛
بعد استخدام الكلمة الأساسية النهائية، لا يمكن للمزامنة تعيين قيمة لها إلا عندما يتم تعريفها، ولا يمكن تعديلها لاحقًا. إذا تم تعيين قيمة للمزامنة في مكان آخر في البرنامج، فلن يتم تجميع البرنامج. في أدوات التطوير مثل Eclipse، سيتم تقديم المطالبات مباشرة في المكان الخطأ.
يمكننا أن نفهم الكتل المتزامنة من منظورين. إذا تم فهمها من منظور أساليب الفصل، فيمكن مزامنة الأساليب المقابلة من خلال متغيرات الفصل. إذا فهمت ذلك من منظور متغيرات الفئة، فيمكنك استخدام الكتل المتزامنة للتأكد من أنه لا يمكن الوصول إلى متغير الفئة إلا بطريقة واحدة في نفس الوقت. بغض النظر عن الزاوية التي تفهمها منها، فإن جوهرها هو نفسه، وهو استخدام متغيرات الفئة للحصول على أقفال المزامنة وتحقيق المزامنة من خلال الاستبعاد المتبادل لأقفال المزامنة.
ملحوظة: عند استخدام الكتل المتزامنة، يجب أن تدرك أن الكتل المتزامنة يمكنها فقط استخدام الكائنات كمعلمات لها. إذا كان نوعًا بسيطًا من المتغيرات (مثل int وchar وboolean وما إلى ذلك)، فلا يمكن استخدام المزامنة للمزامنة.