الكلمة الرئيسية المتزامنة
متزامن ، ندعو الأقفال ، تستخدم بشكل أساسي لقفل الأساليب وكتل التعليمات البرمجية. عند مزامنة طريقة أو كتلة رمز ، يقوم مؤشر ترابط واحد على الأكثر بتنفيذ الرمز في نفس الوقت. عندما تصل مؤشرات الترابط المتعددة إلى كتلة القفل/كتلة الكود في نفس الكائن ، يتم تنفيذ مؤشر ترابط واحد فقط في نفس الوقت ، ويجب أن تنتظر مؤشرات الترابط المتبقية حتى يقوم مؤشر الترابط الحالي بتنفيذ مقطع الرمز قبل التنفيذ. ومع ذلك ، يمكن لخيوط المتبقية الوصول إلى كتل التعليمات البرمجية غير المقفلة في الكائن.
يتضمن المزامنة بشكل أساسي طريقتين: طريقة متزامنة وكتلة متزامنة.
طريقة متزامنة
أعلن الطريقة المتزامنة عن طريق إضافة الكلمة الرئيسية المتزامنة إلى إعلان الطريقة. يحب:
الجمهور المتزامن الفراغ getResult () ؛
تتحكم الطريقة المتزامنة في الوصول إلى متغيرات عضو الفئة. كيف تتجنب التحكم في الوصول إلى متغيرات أعضاء الفصل؟ نحن نعلم أن الطريقة تستخدم الكلمة الرئيسية المتزامنة للإشارة إلى أن الطريقة مغلقة. عندما يصل أي مؤشر ترابط إلى الطريقة المعدلة ، من الضروري تحديد ما إذا كانت مؤشرات الترابط الأخرى "حصرية". كل مثيل فئة يتوافق مع القفل. يجب أن تستدعي كل طريقة متزامنة قفل مثيل الفئة للطريقة قبل تنفيذها. خلاف ذلك ، يتم حظر الخيط الذي ينتمي إليه. بمجرد تنفيذ الطريقة ، سيكون القفل حصريًا. لن يتم إصدار القفل حتى يعود من الطريقة ، ويمكن أن يحصل الخيط المحظور على القفل.
في الواقع ، الطريقة المتزامنة لها عيوب. إذا أعلننا طريقة كبيرة متزامنة ، فسيؤثر ذلك بشكل كبير على الكفاءة. إذا كانت مؤشرات الترابط المتعددة تصل إلى طريقة متزامنة ، فسيقوم مؤشر ترابط واحد فقط بتنفيذ الطريقة في نفس الوقت ، بينما يجب أن تنتظر مؤشرات الترابط الأخرى. ومع ذلك ، إذا لم تستخدم الطريقة المتزامنة ، يمكن لجميع مؤشرات الترابط تنفيذها في نفس الوقت ، مما يقلل من وقت التنفيذ الكلي. لذلك إذا علمنا أن الطريقة لن يتم تنفيذها بواسطة مؤشرات ترابط متعددة أو لا توجد مشكلة في مشاركة الموارد ، فلن نحتاج إلى استخدام الكلمة الرئيسية المتزامنة. ولكن إذا كان يجب علينا استخدام الكلمة الرئيسية المتزامنة ، فيمكننا استبدال الطريقة المتزامنة بواسطة كتلة الكود المتزامن.
كتلة متزامنة
تلعب كتلة التعليمات البرمجية المتزامنة نفس دور الطريقة المتزامنة ، باستثناء أنها تجعل المنطقة الحرجة قصيرة قدر الإمكان. بمعنى آخر ، فإنه يحمي فقط البيانات المشتركة اللازمة ، وترك هذه العملية لكتل الكود الطويلة المتبقية. بناء الجملة كما يلي:
Synchronized (Object) {// Code الذي يسمح بالتحكم في الوصول} إذا احتجنا إلى استخدام الكلمة الرئيسية المتزامنة بهذه الطريقة ، يجب علينا استخدام مرجع كائن كمعلمة. عادةً ما نستخدم هذه المعلمة مثل this.synchronized (this) {// code التي تسمح بالتحكم في الوصول}هناك الفهم التالي للمزامنة (هذا):
1. عندما يصل اثنين من مؤشرات الترابط المتزامنة هذه كتلة الكود المتزامن (هذا) في نفس كائن الكائن ، يمكن تنفيذ مؤشر ترابط واحد فقط خلال فترة واحدة. يجب أن ينتظر مؤشر ترابط آخر حتى يقوم مؤشر الترابط الحالي بتنفيذ كتلة الرمز هذه قبل تنفيذ كتلة الكود.
2. ومع ذلك ، عندما يصل مؤشر ترابط واحد إلى كتلة رمز التزامن (هذا) متزامن للكائن ، لا يزال بإمكان مؤشر ترابط آخر الوصول إلى كتلة رمز التزامن غير المتزامنة (هذا) في الكائن.
3. من الأهمية بمكان أنه عندما يصل مؤشر ترابط إلى كتلة رمز المزامنة (هذا) متزامن للكائن ، سيتم حظر مؤشرات الترابط الأخرى من الوصول إلى جميع كتل رمز التزامن المتزامنة (هذا) في الكائن.
4. ينطبق المثال الثالث أيضًا على كتل رمز التزامن الأخرى. أي عندما يصل مؤشر ترابط إلى كتلة رمز المزامنة (هذا) متزامن لكائن ، فإنه يحصل على قفل كائن هذا الكائن. نتيجة لذلك ، سيتم حظر مؤشرات الترابط الأخرى إلى جميع أجزاء الكود المتزامن لكائن الكائن مؤقتًا.
قفل
هناك مبدأ "تعال أولاً ، تعال لاحقًا" في Java Multithreading ، أي من يمسك بالمفتاح أولاً سيستخدمه أولاً. نعلم أنه لتجنب مشاكل المنافسة في الموارد ، تستخدم Java آليات التزامن لتجنب ، ويتم التحكم في آليات التزامن باستخدام مفهوم الأقفال. إذن كيف تنعكس الأقفال في برامج Java؟ هنا نحتاج إلى معرفة مفهومين:
ما هو القفل؟ في الحياة اليومية ، يكون مانعًا مضافًا إلى الأبواب والمربعات والأدراج وغيرها من الأشياء ، والتي تمنع الآخرين من مختلس النظر أو السرقة ، ويلعب دورًا وقائيًا. وينطبق الشيء نفسه في جافا. تلعب الأقفال دورًا في حماية الأشياء. إذا احتل مؤشر ترابط حصريًا موردًا معينًا ، فلا تريد استخدام مؤشرات ترابط أخرى ، ولكن هل تريد استخدامها؟ لنتحدث عن ذلك عندما انتهيت من استخدامه!
في بيئة تشغيل برنامج Java ، يحتاج JVM إلى تنسيق البيانات المشتركة بين نوعين من مؤشرات الترابط:
1. متغيرات المثيل المحفوظة في الكومة
2. متغيرات الفصل المحفوظة في منطقة الطريقة.
في جهاز Java الظاهري ، يرتبط كل كائن وفئة منطقيا مع الشاشة. بالنسبة للكائن ، تحمي الشاشة المرتبطة متغيرات مثيل الكائن. بالنسبة للفصول ، تحمي الشاشات متغيرات الطبقة. إذا لم يكن للكائن أي متغيرات مثيل ، أو لا يوجد لدى الفئة أي متغيرات ، فلن تراقب الشاشة المرتبطة شيئًا.
من أجل تنفيذ إمكانية المراقبة الحصرية للشاشة ، يربط جهاز Java Virtual Machine قفلًا لكل كائن وفئة. يمثل الامتيازات التي يمكن أن يكون لها مؤشر ترابط واحد فقط في أي وقت. لا تحتاج المواضيع إلى قفل عند الوصول إلى متغيرات المثيل أو متغيرات الفئة. إذا اكتسب مؤشر ترابط قفل ، فمن المستحيل على مؤشرات الترابط الأخرى الحصول على نفس القفل قبل أن يطلق القفل. يمكن لخيط قفل نفس الكائن عدة مرات. لكل كائن ، يحافظ جهاز Java Virtual على عداد القفل. في كل مرة يحصل الخيط على الكائن ، يتم زيادة العداد بمقدار 1 ، وفي كل مرة يتم إطلاقها ، يتم تقليل العداد بمقدار 1. عندما تكون قيمة العداد 0 ، يتم إطلاق القفل بالكامل.
لا يحتاج مبرمجي Java إلى إضافة أقفال بأنفسهم ، وتستخدم أقفال الكائنات داخليًا بواسطة Java Virtual Machines. في برنامج Java ، تحتاج فقط إلى استخدام الكتلة المتزامنة أو الطريقة المتزامنة لتمييز منطقة المراقبة. عندما تدخل منطقة مراقبة ، ستقوم جهاز Java Virtual بإغلاق الكائن أو الفئة تلقائيًا.
قفل بسيط
عند استخدام المزامنة ، نستخدم أقفال مثل هذا:
Througtest الفئة العامة {public void test () {Synchronized (this) {// افعل شيئًا}}}يضمن Synchronized أن مؤشر ترابط واحد فقط هو تنفيذ شيء في نفس الوقت. فيما يلي استخدام القفل بدلاً من المزامنة:
الفئة العامة threadtest {lock lock = new lock () ؛ اختبار void العام () {lock.lock () ؛ // افعل شيئًا lock.unlock () ؛ }}تقوم طريقة Lock () بإغلاق كائن مثيل القفل ، لذلك سيتم حظر جميع مؤشرات الترابط التي تستدعي طريقة القفل () على الكائن حتى يتم استدعاء طريقة Unlock () لكائن القفل.
ما هو مغلق؟
قبل هذا السؤال ، يجب أن نكون واضحين: ما إذا كانت الكلمة الرئيسية المتزامنة إضافة إلى الطريقة أو الكائن ، فإن القفل الذي يكتسبه هو كائن. في Java ، يمكن استخدام كل كائن كقفل ، ينعكس بشكل أساسي في الجوانب الثلاثة التالية:
لطرق التزامن ، يكون القفل هو كائن المثيل الحالي.
بالنسبة إلى كتلة طريقة التزامن ، يكون القفل كائنًا تم تكوينه في الأقواس المتزامنة.
لطرق التزامن الثابت ، يكون القفل هو كائن الفئة للكائن الحالي.
أولاً ، دعونا نلقي نظرة على المثال التالي:
الفئة العامة througtest_01 تنفذ Runnable {Override public synchronized void run () {for (int i = 0 ؛ i <3 ؛ i ++) {system.out.println (thread.currentThread (). getName ()+"Run ......") ؛ }} public static void main (string [] args) {for (int i = 0 ؛ i <5 ؛ i ++) {new thread (new threadtest_01 () ، "thread_"+i) .start () ؛ }}}نتائج التشغيل الجزئي:
thread_2run ... thread_2run ... thread_4run ... thread_4run ... thread_3run ... thread_3run ... thread_3run ... thread_3run ... thread_2run ... thread_4run ...
هذه النتيجة مختلفة بعض الشيء عن النتيجة المتوقعة (هذه الخيوط تعمل هنا). من الناحية المنطقية ، فإن طريقة التشغيل بالإضافة إلى الكلمة الرئيسية المتزامنة ستنتج تأثير المزامنة. يجب أن تنفذ هذه المواضيع طريقة التشغيل واحدة تلو الأخرى. كما ذكر أعلاه ، بعد إضافة كلمات رئيسية متزامنة إلى طريقة عضو ، فهو في الواقع قفل لطريقة الأعضاء. النقطة المحددة هي استخدام الكائن نفسه حيث توجد طريقة العضو كقفل الكائن. ومع ذلك ، في هذا المثال ، لدينا 10 كائنات خيط 10 ، وسيحمل كل مؤشر ترابط قفل كائن كائن مؤشر الترابط الخاص به ، والذي لن ينتج بالتأكيد تأثيرًا متزامنًا. لذلك: إذا تم مزامنة هذه المواضيع ، فيجب مشاركة أقفال الكائن التي تحتفظ بها هذه الخيوط وفريدة من نوعها!
ما هو الكائن الذي تم قفله في هذا الوقت؟ ما يقفله هو تسمية هذا كائن الطريقة المتزامنة. وهذا يعني ، إذا كان كائن Threadtest ينفذ طرق المزامنة في مؤشرات ترابط مختلفة ، فسيشكل حصريًا بشكل متبادل. تحقيق تأثير التزامن. لذا ، قم بتغيير مؤشر الترابط الجديد أعلاه (ThreadTest_01 () جديد ، "Thread_" + i) .start () ؛ إلى مؤشر ترابط جديد (threadtest ، "thread_" + i) .start () ؛
لطرق التزامن ، يكون القفل هو كائن المثيل الحالي.
يستخدم المثال أعلاه الطريقة المتزامنة. لنلقي نظرة على كتلة الكود المتزامن:
الفئة العامة threadtest_02 يمتد مؤشر الترابط {قفل السلسلة الخاصة ؛ اسم السلسلة الخاصة ؛ public threadtest_02 (اسم السلسلة ، قفل السلسلة) {this.name = name ؛ this.lock = قفل ؛ } Override public void run () {synchronized (lock) {for (int i = 0 ؛ i <3 ؛ i ++) {system.out.println (name+"run ......") ؛ }}} public static void main (string [] args) {String lock = new String ("test") ؛ لـ (int i = 0 ؛ i <5 ؛ i ++) {new threadtest_02 ("threadtest_"+i ، lock) .start () ؛ }}}نتائج التشغيل:
ThreadTeTest_0 Run ... Througtest_0 Run ... Througtest_0 Run ... Througtest_1 Run ... Througtest_1 Run ... Througtest_1 Run ... ThreadTest_1 Run ... Througtest_4 Run ...
في الطريقة الرئيسية ، نقوم بإنشاء قفل كائن سلسلة وتعيين هذا الكائن إلى كل قفل متغير مؤشر ترابط مؤشر ترابط 2. نحن نعلم أن هناك تجمع سلسلة في Java ، وبالتالي فإن المتغيرات الخاصة القفل لهذه الخيوط تشير فعليًا إلى نفس المنطقة في ذاكرة الكومة ، أي المنطقة التي يتم فيها تخزين متغيرات القفل في الوظيفة الرئيسية ، وبالتالي فإن قفل الكائن فريد ومشترك. تزامن الموضوع! !
كائن سلسلة القفل الذي تزامن الأقفال هنا.
بالنسبة إلى كتلة طريقة التزامن ، يكون القفل كائنًا تم تكوينه في الأقواس المتزامنة.
الفئة العامة threadtest_03 يمتد Thread {public synchronized static void test () {for (int i = 0 ؛ i <3 ؛ i ++) {system.out.println (thread.currentThread (). getName ()+"run ......") ؛ }} Override public void run () {test () ؛ } main static void main (string [] args) {for (int i = 0 ؛ i <5 ؛ i ++) {new threadtest_03 (). start () ؛ }}}نتائج التشغيل:
Thread-0 Run ... Thread-0 Run ... Thread-0 Run ... Thread-4 Run ... Thread-4 Run ... Thread-4 Run ... Thread-1 Run ... Thread-1 Run ... Thread-1 Run ... Thread-2 Run ... Thread-2 Run ... Thread-2 Run ... Thread-3 Run ... Thread-3 Run ... 3 Run ...
في هذا المثال ، تستخدم طريقة التشغيل طريقة التزامن ، وطريقة التزامن الثابت. إذن ما هو القفل المتزامن هنا؟ نحن نعلم أن الثابت يتجاوز الكائن وهو في مستوى الفصل. لذلك ، فإن قفل الكائن هو مثيل الفئة للفئة حيث يوجد الإصدار الثابت. نظرًا لأن JVM ، تحتوي جميع الفئات المحملة على كائنات فئة فريدة من نوعها ، كائن ThreadTest_03.Class الوحيد في هذه الحالة. بغض النظر عن عدد حالات الفصل الذي ننشئه ، لا يزال مثيله في الفصل واحدًا! لذا فإن قفل الكائن فريد ومشترك. تزامن الموضوع! !
لطرق التزامن الثابت ، يكون القفل هو كائن الفئة للكائن الحالي.
إذا حددت الفئة وظيفة ثابتة متزامنة A ودالة مثيل متزامنة B ، فلن يشكل الكائن نفسه OBJ من هذه الفئة المزامنة عند الوصول إلى طريقتين A و B في مؤشرات ترابط متعددة ، لأن أقفالها مختلفة. إن قفل الطريقة A هو الكائن OBJ ، في حين أن قفل B هو الفئة التي ينتمي إليها OBJ.
قفل الترقية
هناك أربع ولايات في جافا: حالة خالية من القفل ، دولة القفل المتحيزة ، حالة قفل خفيفة الوزن وحالة القفل الثقيلة ، والتي ستتصاعد تدريجياً مع المنافسة. يمكن ترقية القفل ولكن لا يمكن تخفيضه ، مما يعني أنه لا يمكن تخفيض القفل المتحيز إلى القفل المتحيز بعد الترقية إلى قفل خفيف الوزن. هذه الإستراتيجية المتمثلة في قفل الترقية ولكن لا يمكن تخفيضها هي تحسين كفاءة الحصول على الأقفال وإطلاق سراحها. الجزء الرئيسي أدناه هو ملخص للمدونة: التزامن (2) متزامن في Java SE1.6.
قفل تدور
نحن نعلم أنه عندما يدخل مؤشر ترابط إلى طريقة/كتلة المزامنة ، إذا وجد أن طريقة التزامن/كتلة الكود يشغلها الآخرون ، فسوف تنتظر وإدخال حالة حظر. أداء هذه العملية منخفض.
عند مواجهة منافسة القفل ، أو في انتظار الأشياء ، يمكن أن يكون الخيط أقل قلقًا للدخول إلى حالة الحظر ، ولكن انتظر ومعرفة ما إذا كان القفل قد تم إصداره على الفور. هذا هو قفل الدوران. إلى حد ما ، يمكن أن يؤدي قفل الدوران إلى تحسين الخيط.
قفل إيجابي
تستخدم الأقفال الإيجابية بشكل أساسي لحل مشكلة أداء الأقفال دون منافسة. في معظم الحالات ، لا تحتوي أقفال القفل على منافسة متعددة الخيوط فحسب ، بل يتم الحصول عليها دائمًا عدة مرات بواسطة نفس الخيط. من أجل جعل الخيط يكتسب الأقفال بتكلفة أقل ، يتم تقديم أقفال متحيزة. عندما يحصل مؤشر ترابط على قفل ، يمكن للمع من ذلك قفل الكائن عدة مرات ، ولكن في كل مرة يتم فيها تنفيذ هذه العملية ، فإن بعض الاستهلاك النفقات النفقات بسبب تعليمات CAS (CPU المقارنة والرسم). من أجل تقليل هذا النفقات العامة ، يميل القفل إلى أن يكون الخيط الأول للحصول عليه. إذا لم يتم الحصول على القفل من قبل مؤشرات الترابط الأخرى أثناء عملية التنفيذ التالية ، فلن يحتاج مؤشر الترابط الذي يحمل القفل المتحيز أبدًا إلى مزامنة مرة أخرى.
عندما تحاول المواضيع الأخرى التنافس على القفل المتحيز ، يطلق الخيط الذي يحمل القفل المتحيز القفل.
توسيع قفل
مكالمات متعددة أو متعددة للأقفال ذات الحبيبات الصغيرة جدًا ليست فعالة مثل استدعاء الأقفال مع قفل تفريغ كبير.
قفل خفيف الوزن
أساس القفل الخفيف لتحسين أداء التزامن للبرنامج هو "بالنسبة لمعظم الأقفال ، لا توجد منافسة طوال دورة التزامن" ، وهي بيانات تجريبية. يقوم القفل خفيف الوزن بإنشاء مساحة تسمى LOCK في إطار المكدس للخيط الحالي ، والذي يستخدم لتخزين الإشارة الحالية وحالة كائن القفل. إذا لم تكن هناك منافسة ، فإن قفل الوزن الخفيف يستخدم عملية CAS لتجنب النفقات العامة لاستخدام Mutexes ، ولكن إذا كانت هناك منافسة قفل ، بالإضافة إلى النفقات العامة من Mutexes ، تحدث تشغيل CAS بالإضافة إلى ذلك ، لذلك في حالة المنافسة ، سيكون القفل خفيف الوزن أبطأ من قفل الوزن الثقيل التقليدي.
عدالة القفل
عكس الإنصاف هو الجوع. إذن ما هو "الجوع"؟ إذا لم يتمكن مؤشر الترابط من الحصول على وقت تشغيل وحدة المعالجة المركزية لأن مؤشرات الترابط الأخرى تشغل دائمًا وحدة المعالجة المركزية ، فإننا نسمي الموضوع "جائعًا حتى الموت". يسمى الحل للجوع "الإنصاف" - يمكن لجميع المواضيع الحصول على فرص تشغيل وحدة المعالجة المركزية بشكل عادل.
هناك عدة أسباب رئيسية للجوع الخيط:
تستهلك المواضيع ذات الأولوية العالية وقت وحدة المعالجة المركزية لجميع المواضيع ذات الأولوية المنخفضة. يمكننا ضبط أولويته بشكل فردي لكل موضوع ، من 1 إلى 10. كلما ارتفع مؤشر ترابط الأولوية ، زاد الوقت للحصول على وحدة المعالجة المركزية. بالنسبة لمعظم التطبيقات ، من الأفضل عدم تغيير قيمتها ذات الأولوية.
يتم حظر الخيط بشكل دائم في حالة في انتظار دخول كتلة التزامن. تعد منطقة الكود المتزامن في Java عاملًا مهمًا يسبب الجوع في الخيط. لا تضمن كتل التعليمات البرمجية المتزامنة من Java ترتيب مؤشرات الترابط التي تدخلها. هذا يعني أنه من الناحية النظرية ، هناك مؤشر ترابط واحد أو أكثر يتم حظره دائمًا عند محاولة إدخال منطقة الشفرة المتزامنة ، لأن المواضيع الأخرى تتفوق عليها دائمًا للوصول ، مما يؤدي إلى عدم الحصول على فرصة تشغيل وحدة المعالجة المركزية و "الجوع حتى الموت".
الخيط ينتظر كائنًا بحد ذاته ينتظر أيضًا الانتهاء بشكل دائم. إذا كانت مؤشرات الترابط المتعددة على تنفيذ طريقة WAIT () ، ولا تضمن استدعاء الإخطار () عليها أن يتم إيقاظ أي مؤشر ترابط ، فقد يكون أي مؤشر ترابط في حالة انتظار مستمر. لذلك ، هناك خطر من أن يتم إيقاظ موضوع انتظار واحد ، لأنه يمكن دائمًا إيقاظ خيوط الانتظار الأخرى.
لحل مشكلة الخيط "الجوع" ، يمكننا استخدام الأقفال لتحقيق الإنصاف.
إعادة إدخال الأقفال
نحن نعلم أنه عندما يطلب مؤشر ترابط كائنًا يحمل قفلًا بواسطة مؤشر ترابط آخر ، سيتم حظر الخيط ، ولكن هل يمكن أن يكون ناجحًا عندما يطلب مؤشر الترابط كائنًا يحمل قفلًا بنفسه؟ الجواب هو أن النجاح يمكن أن يكون ناجحًا ، وضمان النجاح هو "إعادة دخول" أقفال الخيوط.
"REENTRABLE" يعني أنه يمكنك الحصول على القفل الداخلي الخاص بك مرة أخرى دون حظر. على النحو التالي:
الفئة العامة الأب {public synchronized void method () {// افعل شيئًا}} يمتد طفل الفئة العامة الأب {method public synchronized void method () {// افعل شيئًا super.method () ؛ }}
إذا لم يتم إعادة إدخاله ، فسيتم مسدود الرمز أعلاه ، لأن استدعاء طريقة الطفل () سيحصل أولاً على القفل المدمج لأب الفئة الأصل ثم الحصول على قفل الطفل المدمج. عند استدعاء طريقة فئة الأصل ، تحتاج إلى العودة إلى القفل المدمج لفئة الأصل مرة أخرى. إذا لم يتم إعادة إدخالها ، فقد تقع في حالة خراب.
إن تنفيذ قابلية إعادة إدخال Java Multithreading هو ربط حساب الطلب وخيط يشغله كل قفل. عندما يكون العدد 0 ، يُعتقد أن القفل غير مشغول ، ثم يمكن لأي موضوع الحصول على ملكية القفل. عندما يطلب مؤشر ترابط بنجاح ، سيقوم JVM بتسجيل مؤشر الترابط الذي يحمل القفل وتعيين العدد على 1. إذا طلبت مؤشرات الترابط الأخرى القفل ، فيجب أن تنتظر. عندما يطلب مؤشر الترابط الحصول على القفل مرة أخرى ، سيكون العدد +1 ؛ عندما يخرج الخيط المحتل من كتلة الكود المتزامن ، سيكون العدد -1 ، حتى يتم 0 ، سيتم إصدار القفل. عندها فقط يمكن أن تتاح لها المواضيع الأخرى فرصة للحصول على ملكية القفل.
قفل وفئة التنفيذ
يوفر java.util.concurrent.locks آلية قفل مرنة للغاية ، مما يوفر واجهة وفئة إطار عمل لظروف القفل والانتظار. إنه يختلف عن التزامن المدمج والشاشات ، مما يسمح بمزيد من المرونة في استخدام القفل والظروف. مخطط بنية الفصل الدراسي هو كما يلي:
REENTRANTLOCK: قفل MUTEX REENTRANT ، التنفيذ الرئيسي لواجهة القفل.
reentrantreadwritelock:
ReadWritelock: يحتفظ ReadWritelock بزوج من الأقفال ذات الصلة ، واحدة للعمليات للقراءة فقط والآخر لعمليات الكتابة.
Semaphore: قرار العد.
الشرط: الغرض من القفل هو السماح للموضوع باكتساب القفل ومعرفة ما إذا كان يتم استيفاء حالة معينة.
Cyclicbarrier: فئة مساعدة متزامنة تتيح لمجموعة من الخيوط الانتظار لبعضها البعض حتى تصل إلى نقطة حاجز مشتركة.