اذهب إلى المحتوى
  • 1

الفرق بين دالة notify () ودالة notifyAll () في Java؟

khaled0mohammed

السؤال

Recommended Posts

  • 1

كل من notify و notifyAll هما دالاتان للكلاس thread وتستخدمان لتقديم إشعارات أو تنبيهات (notification) للخيط (thread).
هناك عدة اختلافات أساسية بينهما:

  1. Notification: في حالة ال multiThreading فإن دالة notify تُرسل التنبيه (Notification) إلى خيط واحد فقط من عدة خيوط مُنتظرة (تنتظر تحرير القفل Lock). بينما  notifyAll تقوم بإرساله إلى كل الخيوط التي تنتظر القفل.
  2. من ناحية الأداء: تحتاج notify إلى ذاكرة (Memory) و CPU أقل مقارنةً ب notifyAll (أي أنها أقل استهلاكاً للموارد)، والسبب في ذلك يعود إلى أنها ترسل إشعاراً إلى خيط واحد فقط على عكس notifyAll  التي ترسله إلى كل الخيوط المُنتظرة.
  3. Risk factor (عامل الخطر): في notify  يكون خطر فقدان التنبيه (أو الإشعار) عالي، لإن التنبيه يتم إرساله إلى خيط واحد فقط على عكس notifyAll التي ترسله إلى كل الخيوط المنتظرة وبالتالي إذا فقد أحد الخيوط التنبيه فهناك خيوط أخرى تتلقى التنبيه و يمكنها تنفيذ المطلوب.
  4. Interchangeable أو قابلية التبديل: بالنسبة ل notify فلا يوجد إلا خيط واحد فقط وبالتالي هذه الخاصية ليست موجودة، أما في notifyAll كل الخيوط المُنتظرة تكون قابلة للتبديل.
  5. Thread identification (تحديد الخيط): في حالة notify  فواحد فقط من بين كل الخيوط سيستلم القفل فقط، على عكس notifyAll فمن غير الممكن تحديد أي من الخيوط سيستلم القفل (lock)، حيث أنه يتم إرسال التنبيه إلى كل الخيوط المنتظرة.

مثال يعبر عن حالة استخدام:

public class A {
   public static void main(String[] args){
      B objB = new B();
      objB.start();
      synchronized(objB){
         try{
            System.out.println("Waiting..");
            objB.wait();
         }
         catch(InterruptedException e){
         }
         System.out.println("Total: " + objB.total);
      }
   }
}
class B extends Thread{
   int tot;
   public void run(){
      synchronized(this){
         for(int j=0; j<50 ; j++){
            tot=tot+ i;
         }
         notify();
      }
   }
}

الخرج:

Waiting..
Total : 1148

 

تم التعديل في بواسطة Ali Haidar Ahmad
رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

ببساطة ، يعتمد ذلك على سبب انتظار سلاسل الرسائل الخاصة بك. هل تريد أن تخبر أحد سلاسل الرسائل المنتظرة أن شيئًا ما قد حدث ، أم أنك تريد أن تخبرهم جميعًا في نفس الوقت؟

في بعض الحالات ، يمكن لجميع سلاسل انتظار الانتظار اتخاذ إجراء مفيد بمجرد انتهاء الانتظار. مثال على ذلك هو مجموعة من مؤشرات الترابط في انتظار انتهاء مهمة معينة ؛ بمجرد انتهاء المهمة ، يمكن لجميع خيوط الانتظار متابعة أعمالهم. في مثل هذه الحالة ، يمكنك استخدام notifyAll () لاستيقاظ جميع سلاسل انتظار الانتظار في نفس الوقت.

حالة أخرى ، على سبيل المثال قفل متبادل ، يمكن لواحد فقط من خيوط الانتظار أن تفعل شيئًا مفيدًا بعد أن يتم إعلامك (في هذه الحالة تحصل على القفل). في مثل هذه الحالة ، تفضل استخدام الإخطار () . تم التنفيذ بشكل صحيح ، يمكنك استخدام notifyAll () في هذه الحالة أيضًا ، لكنك ستستيقظ دون داع سلاسل الرسائل التي لا تستطيع فعل أي شيء على أي حال.

في كثير من الحالات ، سيتم كتابة الشفرة التي تنتظر الشرط كحلقة:

 synchronized(o) {
    while (! IsConditionTrue()) {
        o.wait();
    }
    DoSomethingThatOnlyMakesSenseWhenConditionIsTrue_and_MaybeMakeConditionFalseAgain();
}

وبهذه الطريقة ، إذا استدعت مكالمة o.notifyAll() أكثر من خيط انتظار واحد ، وأول من يُرجع من o.wait() يجعل الحالة في الحالة الخاطئة ، فإن الآخر ستعود المواضيع التي تم إيقاظها إلى الانتظار.

رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...