**ترجمة النص إلى اللغة العربية:**
في لغة البرمجة جافا، تحتوي فئة Object على ثلاثة أساليب نهائية تتيح للمواضيع التواصل بشأن حالة القفل للمورد. هذه الأساليب هي wait()، notify()، و notifyAll(). لذا، سنقوم اليوم بالتحقق من استخدام wait، notify، و notifyAll في برنامج جافا.
wait، notify و notifyAll في جافا
يجب أن يكون للموضوع الحالي الذي يستدعي هذه الأساليب على أي كائن monitor وإلا فإنه يثير استثناء java.lang.IllegalMonitorStateException.
wait
أساليب انتظار الكائن لديها ثلاثة أشكال، الأولى تنتظر بشكل لا نهائي حتى يستدعي أي خيط آخر أسلوب notify أو notifyAll على الكائن ليوقظ الخيط الحالي. الأشكال الأخرى الاثنتين تضعان الخيط الحالي في حالة انتظار لفترة زمنية محددة قبل أن يتم استيقاظه.
notify
طريقة notify توقظ فقط خيطًا واحدًا في حالة الانتظار على الكائن، ويبدأ تنفيذ هذا الخيط. لذلك، إذا كان هناك عدة خيوط في حالة انتظار على كائن ما، ستوقظ هذه الطريقة فقط واحدة منهم. اختيار الخيط الذي سيتم استيقاظه يعتمد على تنفيذ نظام التحكم في الخيوط في نظام التشغيل.
notifyAll
طريقة notifyAll توقظ جميع الخيوط في حالة الانتظار على الكائن، على الرغم من أنه يعتمد على تنفيذ نظام التشغيل أي منها سيتم معالجته أولاً. يمكن استخدام هذه الطرق لتنفيذ مشكلة المنتج والمستهلك حيث تكون الخيوط المستهلكة في حالة انتظار الكائنات في الطابور، وتقوم الخيوط الإنتاجية بوضع الكائن في الطابور وإعلام الخيوط الانتظار. دعونا نرى مثالًا حيث تعمل عدة خيوط على نفس الكائن ونستخدم طرق الانتظار والإعلام السابقة.
Message
A java bean class on which threads will work and call wait and notify methods.
package com.journaldev.concurrency;
public class Message {
private String msg;
public Message(String str){
this.msg=str;
}
public String getMsg() {
return msg;
}
public void setMsg(String str) {
this.msg=str;
}
}
Waiter
A class that will wait for other threads to invoke notify methods to complete it’s processing. Notice that Waiter thread is owning monitor on Message object using synchronized block.
package com.journaldev.concurrency;
public class Waiter implements Runnable{
private Message msg;
public Waiter(Message m){
this.msg=m;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
synchronized (msg) {
try{
System.out.println(name+" waiting to get notified at time:"+System.currentTimeMillis());
msg.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(name+" waiter thread got notified at time:"+System.currentTimeMillis());
//قم بمعالجة الرسالة الآن
System.out.println(name+" processed: "+msg.getMsg());
}
}
}
المنبه
A class that will process on Message object and then invoke notify method to wake up threads waiting for Message object. Notice that synchronized block is used to own the monitor of Message object.
package com.journaldev.concurrency;
public class Notifier implements Runnable {
private Message msg;
public Notifier(Message msg) {
this.msg = msg;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name+" started");
try {
Thread.sleep(1000);
synchronized (msg) {
msg.setMsg(name+" Notifier work done");
msg.notify();
// msg.notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
اختبارWaitNotify
فئة اختبار ستقوم بإنشاء عدة خيوط من Waiter و Notifier وتشغيلها.
package com.journaldev.concurrency;
public class WaitNotifyTest {
public static void main(String[] args) {
Message msg = new Message("process it");
Waiter waiter = new Waiter(msg);
new Thread(waiter,"waiter").start();
Waiter waiter1 = new Waiter(msg);
new Thread(waiter1, "waiter1").start();
Notifier notifier = new Notifier(msg);
new Thread(notifier, "notifier").start();
System.out.println("All the threads are started");
}
}
عندما نقوم بتنفيذ البرنامج أعلاه، سنرى الإخراج أدناه ولكن البرنامج لن يكتمل لأن هناك خيطين في انتظار على كائن الرسالة وأسلوب notify() قام بإيقاظ أحدهما فقط، والخيط الآخر لا يزال في انتظار الإشعار.
waiter waiting to get notified at time:1356318734009
waiter1 waiting to get notified at time:1356318734010
All the threads are started
notifier started
waiter waiter thread got notified at time:1356318735011
waiter processed: notifier Notifier work done
إذا قمنا بتعليق النداء notify() وفك تعليق النداء notifyAll() في فئة Notifier، سيكون الإخراج كما يلي.
waiter waiting to get notified at time:1356318917118
waiter1 waiting to get notified at time:1356318917118
All the threads are started
notifier started
waiter1 waiter thread got notified at time:1356318918120
waiter1 processed: notifier Notifier work done
waiter waiter thread got notified at time:1356318918120
waiter processed: notifier Notifier work done
نظرًا لأن طريقة notifyAll() توقظ كل من خيوط Waiter، يتم إكمال البرنامج وإنهاءه بعد التنفيذ. هذا كل شيء بخصوص wait، notify و notifyAll في جافا.
Source:
https://www.digitalocean.com/community/tutorials/java-thread-wait-notify-and-notifyall-example