ما هو Java Semaphore و Mutex - وأوضح Java Concurrency MultiThread مع المثال

نشرت: 2015-03-12

Java Mutex and Semaphore Tutorial by Crunchify

يعد التزامن جافا موضوعًا واسعًا جدًا. هناك المئات من البرامج التعليمية والأمثلة المتاحة للاستخدام. في بعض الوقت ، كتبت بعض البرامج التعليمية حول تشغيل خيوط متعددة بشكل متزامن في Java وأنواع مختلفة من الكتل المتزامنة.

في هذا البرنامج التعليمي سوف ننتقل إلى ما يلي:

  1. شرح موتكس
  2. شرح السيمافور
  3. مثالان مع التفاصيل

هيا بنا نبدأ

Let's keep this in mind أثناء قراءة الشرح أدناه:

  • خذ مثالا على المتسوق والعميل
  • المتسوق يستعير أجهزة الكمبيوتر المحمولة
  • يمكن للعميل القدوم واستخدام الكمبيوتر المحمول - يحتاج العميل إلى مفتاح لاستخدام الكمبيوتر المحمول
  • بعد الاستخدام - يمكن للعميل إعادة الكمبيوتر المحمول إلى Shopper

ما هو موتكس (خيط واحد فقط):

المتسوق لديه مفتاح لجهاز كمبيوتر محمول. يمكن لعميل واحد الحصول على المفتاح - استعارة كمبيوتر محمول - في ذلك الوقت. عند انتهاء المهمة ، يعطي المتسوق (يحرر) المفتاح للعميل التالي في قائمة الانتظار.

Official Definition :

"يستخدم كائن المزامنة عادةً في إجراء تسلسل للوصول إلى قسم من re-entrant code الذي cannot be executed concurrently بأكثر من مؤشر ترابط واحد. يسمح كائن كائن المزامنة (mutex) بخيط واحد فقط في قسم متحكم فيه ، مما يجبر الخيوط الأخرى التي تحاول الوصول إلى هذا القسم على الانتظار حتى خروج سلسلة الرسائل الأولى من هذا القسم. "

بمعنى آخر: Mutex = Mutually Exclusive Semaphore

ما هو سيمافور (ن المواضيع المحددة):

لنفترض الآن أن لدى Shopper 3 أجهزة كمبيوتر محمولة متطابقة و 3 مفاتيح متطابقة. Semaphore هو عدد free identical Laptop keys . تم تعيين عدد الإشارات - عدد المفاتيح - على 3 في البداية (جميع أجهزة الكمبيوتر المحمولة الثلاثة مجانية) ، ثم تنخفض قيمة العد عندما يأتي العميل. إذا كانت جميع أجهزة الكمبيوتر المحمولة قيد الاستخدام ، أي لا توجد مفاتيح مجانية متبقية لـ الكمبيوتر المحمول ، عدد الإشارات هو 0. الآن ، عندما يقوم أي عميل بإرجاع الكمبيوتر المحمول ، يتم زيادة الإشارة إلى 1 (مفتاح مجاني واحد) ، ويتم إعطاؤها للعميل التالي في قائمة الانتظار.

Official Definition : "الإشارة تقيد عدد المستخدمين المتزامنين لمورد مشترك بحد أقصى. يمكن أن تطلب الخيوط الوصول إلى المورد (تقليل الإشارة) ، ويمكن أن تشير إلى أنها انتهيت من استخدام المورد (بزيادة الإشارة). "

يجب قراءة آخر: Lazy Creation of Singleton ThreadSafe Instance

مثال 1: (الشرح أدناه)

في البرنامج التعليمي أعلاه CrunchifySemaphoreMutexTutorial.java عندما يضيف CrunchifyProducer threadName إلى كائن crunchifyList المرتبط ، فإنه يمكن أن يشير إلى الإشارة.

يمكن بعد ذلك أن يحاول CrunchifyConsumer الحصول على الإشارة لذلك سينتظرون حتى يقوم CrunchifyProducer بالإشارة إلى إضافة threadID. عند الإشارة إلى بيانات مضافة ، سيتم إيقاظ أحد المستهلكين وسيعرف أنه يمكنه قراءة كائن crunchifyList. يمكنه قراءة قائمة ، ثم العودة إلى محاولة الحصول على الإشارة.

إذا كتب المنتج في ذلك الوقت حزمة أخرى ، فقد أشار مرة أخرى وسيقوم أي من المستهلكين بعد ذلك بقراءة حزمة أخرى وما إلى ذلك ...

بعبارات أخرى:

نتيجة:

كيفية منع حالة السباق:

What if you have multiple Consumers? في شرح Java التعليمي أعلاه ، يجب على المستهلكين (وليس المنتجين) قفل المخزن المؤقت عند قراءة الحزمة (ولكن ليس عند الحصول على الإشارة) لمنع ظروف السباق. في المثال أدناه ، يقوم المنتج أيضًا بتأمين القائمة نظرًا لأن كل شيء موجود على نفس JVM.

المثال 2:

نتيجة: