لنستخدم تشبيهًا: الشيء يشبه المنزل الكبير، الباب مفتوح دائمًا. هناك العديد من الغرف (المعروفة أيضًا باسم الأساليب) في المنزل. تكون هذه الغرف إما مقفلة (الطريقة المتزامنة) أو غير مقفلة (الطريقة العادية). يوجد مفتاح على باب الغرفة. هذا المفتاح يمكنه فتح جميع الغرف المغلقة. بالإضافة إلى ذلك، أقوم بمقارنة جميع المواضيع التي تريد استدعاء أساليب هذا الكائن بالأشخاص الذين يريدون الدخول إلى غرفة معينة في هذا المنزل. هذا كل ما في الأمر، دعونا نلقي نظرة على كيفية عمل هذه الأشياء مع بعضها البعض.
هنا نوضح أولاً متطلباتنا الأساسية. يحتوي الكائن على طريقة متزامنة واحدة على الأقل، وإلا فلن يكون لهذا المفتاح أي معنى. وبطبيعة الحال، لن يكون هناك مثل هذا الموضوع لدينا.
يريد شخص الدخول إلى غرفة مغلقة، فيصل إلى باب المنزل ويرى المفتاح هناك (يشير إلى أنه لا يوجد أحد آخر يريد استخدام الغرفة المغلقة بعد). لذلك صعد وحصل على المفاتيح واستخدم الغرف كما خطط له. لاحظ أنه يعيد المفتاح مباشرة بعد كل استخدام للغرفة المغلقة. حتى لو أراد استخدام غرفتين مقفلتين على التوالي، عليه إعادة المفتاح واستعادته بينهما.
ولذلك فإن مبدأ استخدام المفاتيح في الظروف العادية هو: "استعرها كما تستخدمها، وأعدها بمجرد استخدامك لها".
في هذا الوقت، يمكن لأشخاص آخرين استخدام الغرف المفتوحة دون قيود. يمكن لشخص واحد استخدام غرفة واحدة، أو يمكن لشخصين استخدام غرفة واحدة. ولكن إذا أراد شخص ما الدخول إلى غرفة مغلقة، عليه أن يركض إلى الباب وينظر. إذا كان لديك المفتاح، بالطبع يمكنك أخذه والمغادرة. إذا لم يكن لديك المفتاح، فلا يمكنك سوى الانتظار.
إذا كان العديد من الأشخاص ينتظرون المفتاح، فمن سيحصل عليه أولاً عندما يتم إرجاع المفتاح؟ غير مضمون. مثل الرجل في المثال السابق الذي يريد استخدام غرفتين مقفلتين على التوالي، إذا كان هناك أشخاص آخرون ينتظرون المفتاح عندما يعيد المفتاح، فليس هناك ما يضمن أن هذا الرجل يمكنه الحصول عليه مرة أخرى. (تنص مواصفات JAVA بوضوح في العديد من الأماكن على عدم وجود ضمانات، مثل المدة التي سيستغرقها Thread.sleep() للعودة إلى التشغيل بعد فترة راحة، وأي خيط له نفس الأولوية سيتم تنفيذه أولاً، ومتى سيتم تنفيذ الأمر يتم تحرير القفل للوصول إلى الكائن، وستحدد سلاسل الرسائل المتعددة في تجمع الانتظار أي مؤشر ترابط سيحصل على الأولوية، وما إلى ذلك. أعتقد أن القرار النهائي يقع على عاتق JVM، والسبب في عدم وجود ضمان هو أنه عندما يتخذ JVM القرار أعلاه. إنه لا يصدر حكمًا بناءً على شرط فحسب، بل وفقًا للعديد من الشروط، فقد يؤثر ذلك على الترويج لـ JAVA، ولكنني أعتقد ذلك هذه ليست غير معقولة، وليست غير مؤكدة تمامًا، لأن الكمبيوتر نفسه يعمل وفقًا للتعليمات، حتى لو كانت تبدو عشوائية، فهناك في الواقع قواعد يمكن العثور عليها أجهزة الكمبيوتر هي أرقام عشوائية زائفة يتم كتابتها من قبل أشخاص باستخدام طريقة معينة، ويبدو أنها عشوائية بالإضافة إلى ذلك، قد يكون ذلك بسبب أنها مزعجة للغاية ولا معنى لها لتحديدها، لذلك إذا لم تكن متأكدًا، فأنت غير متأكد. .)
دعونا نلقي نظرة على كتل التعليمات البرمجية المتزامنة مرة أخرى. إنها مختلفة قليلاً عن طريقة المزامنة.
1. من حيث الحجم، تكون كتل التعليمات البرمجية المتزامنة أصغر من الطرق المتزامنة. يمكنك التفكير في كتلة التعليمات البرمجية المتزامنة كمساحة في غرفة غير مقفلة مفصولة بشاشة مقفلة.
2. يمكن لكتلة كود المزامنة أيضًا تحديد مفتاح كائن آخر يدويًا. إنه مثل تحديد المفتاح الذي يمكن استخدامه لفتح قفل هذه الشاشة، يمكنك استخدام مفتاح هذا المنزل، ويمكنك أيضًا تحديد مفتاح منزل آخر لفتحه لفتح القفل، احصل على هذا المفتاح واستخدم مفتاح المنزل لفتح الشاشة المقفلة لهذا المنزل.
تذكر أن مفتاح منزل آخر حصلت عليه لا يمنع الآخرين من دخول الغرف المفتوحة في ذلك المنزل.
لماذا نستخدم كتل التعليمات البرمجية المتزامنة؟ أعتقد أن الأمر يجب أن يكون على النحو التالي: أولاً وقبل كل شيء، يؤثر جزء المزامنة في البرنامج على كفاءة التشغيل، وعادةً ما تقوم الطريقة بإنشاء بعض المتغيرات المحلية أولاً، ثم تقوم ببعض العمليات على هذه المتغيرات، مثل الحسابات والعرض وما إلى ذلك. وأغطية المزامنة كلما زاد عدد التعليمات البرمجية، كلما كان التأثير أكثر خطورة على الكفاءة. لذلك نحاول عادةً إبقاء نطاق تأثيرها صغيرًا قدر الإمكان. كيف تفعل ذلك؟ كتل التعليمات البرمجية المتزامنة. نحن نقوم فقط بمزامنة أجزاء الطريقة التي يجب مزامنتها، مثل العمليات.
بالإضافة إلى ذلك، يمكن لكتلة كود المزامنة تحديد المفتاح. تتمتع هذه الميزة بفائدة إضافية تتمثل في شغل مفتاح كائن ما خلال فترة زمنية معينة. تذكر ما قلته من قبل عن مبادئ استخدام المفاتيح في الظروف العادية. هذه ليست ظروف عادية. لا يتم إرجاع المفتاح الذي حصلت عليه إلى الأبد، ولكن يتم إرجاعه فقط عند الخروج من كتلة التعليمات البرمجية المتزامنة.
دعونا نستخدم تشبيه الرجل السابق الذي أراد استخدام غرفتين مقفلتين على التوالي. كيف يمكنني الاستمرار في استخدام غرفة أخرى بعد استخدام غرفة واحدة؟ استخدم كتل التعليمات البرمجية المتزامنة. قم أولاً بإنشاء مؤشر ترابط آخر، وقم بإنشاء كتلة رمز المزامنة، وقم بتوجيه قفل كتلة الرمز هذه إلى مفتاح المنزل. ثم ابدأ هذا الموضوع. طالما يمكنك الحصول على مفتاح المنزل عند دخولك كتلة التعليمات البرمجية هذه، يمكنك الاحتفاظ به حتى تخرج من كتلة التعليمات البرمجية هذه. بمعنى آخر، يمكنك حتى اجتياز جميع الغرف المغلقة في هذه الغرفة، وحتى النوم (10*60*1000)، ولكن لا يزال هناك 1000 خيط في انتظار المفتاح عند الباب. انها ممتعة للغاية.
دعونا نتحدث عن العلاقة بين طريقة النوم () والمفتاح. إذا تم إجبار مؤشر الترابط على وضع السكون () بعد الحصول على المفتاح ولم يكمل محتوى المزامنة، فسيظل المفتاح موجودًا. لن يتم إرجاع المفتاح حتى يتم تشغيله مرة أخرى واكتمال كافة محتويات المزامنة. تذكر أن الرجل كان متعبًا من العمل وذهب ليأخذ قسطًا من الراحة ولم يكمل ما أراد القيام به. ومن أجل منع الآخرين من دخول الغرفة وإحداث الفوضى في الداخل، كان عليه أن يرتدي المفتاح الوحيد على جسده حتى أثناء النوم.
وأخيرا، قد يتساءل قائل، لماذا نحتاج إلى مفتاح واحد لفتح كل باب، بدلا من مفتاح واحد لكل باب؟ أعتقد أن هذه مسألة تعقيد بحتة. من المؤكد أن مفتاحًا واحدًا لباب واحد أكثر أمانًا، لكنه سيتضمن الكثير من المشاكل. إنشاء المفاتيح وتخزينها واكتسابها وإعادتها وما إلى ذلك. قد يزيد تعقيدها هندسيًا مع زيادة عدد طرق المزامنة، مما يؤثر بشكل خطير على الكفاءة. ويمكن اعتبار هذا بمثابة مسألة مقايضة. كم هو غير مرغوب فيه تقليل الكفاءة بشكل كبير من أجل زيادة القليل من الأمان.