الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

Concurrency In Java

بدأه asminf في 2 يناير 2009 · 16 رد · 3,338 مشاهدة · في JavaSE
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكــم ورحمـة الله وبركاتــه

اطلعت حديثا على موضوع الأخ عيسى حول Threads in java فوددت التعقيب ولكن للأسف الموضوع أغلق.

أشكر الأخ Eisa على شرحه القيم و الواضح جدا.

أود أن أعقب فقط عن أن Concurrency programming أتت بعد

Sequenced programing أين كانت الحاجة لتنفيذ برنامج واحد بصفة تسلسلية لتعليماته ، ومع مرور الوقت وتطور التكنولوجيا ظهرت الحاجة لتنفيذ عدة برامج في آن واحد و المشكل يكمن فيما إذا كانت هذه البرامج مرتبطة فيما بينها"تستعمل متغير أومورد مشترك

هذه البرامج تدعى Concurrency programs أي dependence

ولأجل أن يكون سير هته البرامج صحيح و سليم ، هناك آليات للتزامن مثل Semaphore and Monitor..

بالنسبة للغة الجافا هي تدعم ال Monitor وذلك باستخدامها للكلمة المفتاح sunchronized في دوالها ، والتي تضمن تنفيذها من طرف ثريد واحد at time. واستخدامها للدالتين Wait and Notify لضمان هذا التزامن بين مختلف الثريدس.

توجد نماذج أساسية لل Concurrency ومنها مثلا : Reader_writer, Pruduceer-consommer, mutual exclusion,…

و التي من خلالها يمكن حل مختلف المشاكل الأخرى لأجل بناء تطبيقات Concurrency and cooperatives.

آسف عن المقدمة التي يمكن أن تكون ثقيلة نوعا ما و لنذهب للتطبيق.

أضع بين أيديكم مشكلة للحل لضمان التزامن بين الثريدس"الطلبة هنا في المثال".

-نود أن نضمن السير الحسن لدخول وخروج الطلبة من قاعة متكونة من قاعتين داخليتين A an B

كما هو موضح بالشكل :

exeti8.png

هناك مجوعة طلبة خارجا ، على كل طالب القيام بالأشغال التاليةعلى الترتيب:

-البقاء خارجا لمدة معينة.

-الدخول للقاعة A"الباب 1"

-البقاء في القاعة A مدة معينة.

-الإنتقال من A للقاعة B"الباب 2"

-البقاء في القاعة B لمدة معينة.

-الإنتقال من B للقاعة A"الباب 3"

-البقاء في القاعة A لمدة معينة.

-الخروج خارجا "الباب 4"

ولكن هناك شروط توضع في الحساب وهي:

الغرفة A لا تتجاوز 10 طلبة ، والغرفة B لا تتجاوز 05 طلبة.

أضع بين أيديكم هذا المشكل للمناقشة فهل من مجيب أو من معقب؟

#2

السلام عليكم

شكراً لك أخوي asmif على تعقيبك الجميل و الرائع, ولكن أنا عندي مثال اشتغلت عليه في يوم من الأيام وإن شاء الله إنه يوضح الصورة أكثر (كلنا نهدف إلى إيصال المعلومة و لست أقصد بأن شرحك غير واضح لا سمح الله). كما قال الأخ asmif فإن الـ concurrency يعني تنفيذ عدة عمليات في آن واحد يعني مثل لو يكون عندنا برنامج chatting فإن الـ method اللي تضيف مستخدمين على الـ chatting أو التي تحذفهم من قائمة الموجودين في الـ chatting يجب أن تكون مضاف إليها الكلمة المحجوزة synchronized في الـ method signature وذلك للسماح بالإضافة و الحذف في نفس الوقت. طيب المثال هذا مو واضح, فيه مثال آخر: مثلا لو يكون عندنا ملف و يعمل عليه أكثر من شخص على الشبكة فإن الوصول إلى هذا الملف يجب أن يكون synchronous بحيث يسمح للجميع بالوصول للملف في نفس الوقت.

#3

السلام عليكــم ورحمـة الله وبركاتــه

أشكرك أخي على مشاركتك في الموضوع و تعقيبك و خصوصا سردك للأمثلة الحية و الملموسة.

بصراحة أنا لست بالخبيرة في ميدان ال cuncurrencuy in java ولكن استخدمتها سابقا في أمثلة تطبيقية.

أتمنى أن يكون هناك العديد من المشاركين في الموضوع لإثراءه وتصحيح الأخطاء التي تظهر به.

اليوم سأحاول أن أشرح قليلا استخدام المونيتر في الجافا :

-الكلمة المفتاح synchronized في دوال الجافا تضمن تنفيذها in mutual Exclusion ما بين مختلف ال processes .

- داخل الميتود سنكرونيزد ، توجد 2 متود للتزامن و التواصل بين مختلف الثريدس:

Wait(): تضع الثريد في حالة انتضار "يتوقف عن العمل في انتضار notify()"

Notify(): تحفز ثريد موقف ب wait()

مثال شهير : عدة process تغير في متغير مشترك compte-client

Procedure Compte ;

Compte_Client :integer=0;//variable commune

Process Pi

Var x:integer=0;//local variable of Pi

Begin

//outside Critical section actions…

x= Compte_Client;

x=x+1;

Compte_Client=x;

..

End

إذا قام 2 بروسس بالتنفيذ للكود الذي يحوي المتغير المشترك في آن واحد من المحتمل الحصول عل نتيجة خاطئة ل Compte_Client

ولهذا سنحل هذا المشكل باستخدام المونتر بالجافا

نمثل كل بروسس بثريد الذي يرمز لأي Client

*كل Client يملك هوية خاصة id

*ويقوم مثلا بعمل ما -هنا ممثل بloop تنفذ10 مرات-

*وبعدها يقوم بتغيير القيمة Compte_Client in mutual exclusion باستدعاء compte.CriticalSection متود

public class Client extends Thread{



/** Creates a new instance of Client */

public Client(Compte compte, int id) {

this.compte=compte; 

this.id=id;

}

public void run(){



/////////Hors critical section Actions....

for (int i=1;i<=10;i++){

System.out.println("client "+id+ "step "+i);

}

//Enter to the critical section

compte.CriticalSection(id);



}

private Compte compte;

private int id; 



}



وهاهو محتوى المونيتور

//Monitor 

public class Compte {

private int Compte_Client=0; //Compte_Client Variable partagé



//Method executed in mutual exclusion

public synchronized void CriticalSection(int id){

int X = Compte_Client; 

X = X+1;

Compte_Client=X;

System.out.println("Client n°= " + id +" Compte " + Compte_Client);

notifyAll();//release all blocked process 

}



}



وهاهو الآن الكلاس ماين الذي يصنع ويطلق تنفيذ Client threads

public class Main {



public static void main(String[] args) {

Compte c= new Compte();

Client[] cl = new Client[30];

//Creation and lanching of 30 client objects.

for(int i=0;i< 30;i++){

cl= new Client(c,i);

cl.start();

}

}



}

ان شاء الله الأمور صارت أوضح.

الآن عودة لمشكل القاعة و الطلبة .في رأيكم من الذي يجسد دور البروسس"ثريدس"؟ وأين تكمن السانونكرونايزد متودس ؟ أي جواب ، أي تعقيب الموضوع مفتوح ....

#4

شرح جميل و مفيد يا أختي asminf

أتمنى ممن يفهم هذا الموضوع إنه يجاوب على السؤال الذي وضعته الأخت.

شكراً

#5

العفو أخي

ولكن اعتقد أن السؤال الأول جد سهل...

#6

السلام عليكــم ورحمـة الله وبركاتــه

سأواصل بالإجابة على السؤالين الأخيرين.

1-الذي يجسد دور الثريد هو من يقوم بالأعمال المذكورة سابقا

-البقاء خارجا لمدة معينة.

-الدخول للقاعة A"الباب 1"

-البقاء في القاعة A مدة معينة.

-الإنتقال من A للقاعة B"الباب 2"

-البقاء في القاعة B لمدة معينة.

-الإنتقال من B للقاعة A"الباب 3"

-البقاء في القاعة A لمدة معينة.

-الخروج خارجا "الباب 4"

إذن بالتأكيد الطالب هو المجسد بالثريد :D

2-سانكرونايزد متودس هي ما تكون مشتركة بين مختلف الطلبة والتي يجب أن تكون ذات وصول متناوب كي لا يحدث انتربلوكاج ، one thread at time excute this method.

في المشكل المطروح نرى بأن هناك 4موارد مشتركة "Shared resources" فبالتأكيد لن يدخل الباب عشرة في آن واحد لازم واحد وراء واحد ، بالصف :P

إذن المونتر نمثلها بالقاعة ككل وبها أربعة متود للتزامن:

//Enter from exterior to classA

public synchronized void tEVA(int id) {....}

//Enter from classA to classB

public synchronized void tAVB(int id) {....}

//Enter from classB to classA

public synchronized void tBVA(int id) {....}

//Enter from classA to exterior

public synchronized void tAVE(int id) {....}

id تمثل هوية الطالب.

الآن يبقى منكم أن تخمنو عن محتوى المتودس الأربعة

أي كيف نستطيع أن نضمن الدخول والخروج من الأبواب الأربعة للطلبة بدون تزاحم وبدون إخلال بشرط قدرة تحمل كل قاعة A or B من الطلبة

وهنا أين يتم استخدام ال wait() و Notify() methods

#7

ما شاء الله عليك يا asminf أحس إنك متحمسة للموضوع, بس المشكلة ما أشوف فيه أحد متفاعل مع هالموضوع غيرنا احنا الاثنين (الاثنين ولا الأحد ههههههه :blink: :blush: )

#8

بالعكس يا lovelorn2008 انا متابع الموضوع معكن ولكن بصمت

وعجبني التحليل asminf ما شاء الله

ready to do full students projects

digitalscenter@hotmail.com

+966530357742

#9

السلام عليكــم ورحمـة الله وبركاتــه

اقتباس
ما شاء الله عليك يا asminf أحس إنك متحمسة للموضوع, بس المشكلة ما أشوف فيه أحد متفاعل مع هالموضوع غيرنا احنا الاثنين (الاثنين ولا الأحد ههههههه

أشكرك أخي على ردك المحبط ، ولكن سأكمل متحمسة رغم ... :lol: ، إن لم يلقى هذا الموضوع صدى اليوم فغدا ، بعد غد،.. العام المقبل، ان شاء الله

اقتباس
العكس يا lovelorn2008 انا متابع الموضوع معكن ولكن بصمت

وعجبني التحليل asminf ما شاء الله

أشكرك كثيرا أخ عصام على تتبعك واطرائك.

عودة لآخر نقطة والتي كانت حول محتوى السانكونايزد متودس ، والتي تكون في بنية تجعل كل الثريدس على صلة بهذه المتودس ألا وهي المونيتر وفي الجافا نستطيع تمثيلها بكلاس اسمه "salle/class"حسب مثالنا هذا

public class Salle{



//common variables for objects of class*must declared private*

private int NPA=0;//Number of students in A

private int NPB=0;//Number of students in B

private int NAEnEntre=0;//Number of students in A come from E and not from B.



//**les procedures externes

//Entrer de l'exterieur vers la salle A

public synchronized void tEVA(int id) {

while(((NAEnEntre==9)&&(NPB==5))||(NPA==10)) try{wait();}

catch(InterruptedException e){}

NPA++;

NAEnEntre++; 

System.out.println("L'etudiant n°= " + id +

" [E_A] Nbr dans A " + NPA +" NAEnEntre dans A " + NAEnEntre+" Nbr dans B " + NPB);

notifyAll();

}

//Entrer de la salle A vers la Salle B

public synchronized void tAVB(int id) { ... }


//Entrer de la salle B vers la Salle A

public synchronized void tBVA(int id) { ... }


//Entrer de la salle A vers la Salle L'exterieure

public synchronized void tAVE(int id) { ... } 

}

الشرح يأتي لاحقا..

تم تعديل هذه المشاركة بواسطة asminf في 7 يناير 2009 في 00:17

#10

يعطيكي العافية بانتظار الشرح بس لو انو تستعملي الكلمات باللغة الانكليزية لأنو الفرنسي تبعي صفر :wacko:

ready to do full students projects

digitalscenter@hotmail.com

+966530357742

#11
asminf كتب:
أشكرك أخي على ردك المحبط ، ولكن سأكمل متحمسة رغم ... :lol: ، إن لم يلقى هذا الموضوع صدى اليوم فغدا ، بعد غد،.. العام المقبل، ان شاء الله

إلى الأمام asminf بس أنا حبيت أضفي جو من المرح لا أكثر, وإذا إنك تحسستي من هاي الشغلة فأنا آسف والله.

#12

طبعا هناك مقدرين و مهتمين بالموضوع و لكن قد نحن البشر لا نكون متزامنين في الاهتمامات :)

ممكن ان اعرف الرابط الاصلي الخاص بالاخ عيسى بما ان هذا تعليق فاي شخص يدفعه الفضول للاطلاع على الموضوع الاصلي

و شكرا

Theory is when you know something, but it doesn't work. Practice is when something works, but you don't know why. Programmers combine theory and practice: Nothing works and they don't know why

#13

السلام عليكــم ورحمـة الله وبركاتــه

أشكرك الأخ عصام مايكون غير خاطرك ،سأحاول كتابة التعليقات بالإنجليزية من الآن فصاعدا

وشكرا لكLovelorn2008 ولروحك المرحة ولا داعي للحلف صدقتك، أهلا وسهلا

اقتباس
طبعا هناك مقدرين و مهتمين بالموضوع و لكن قد نحن البشر لا نكون متزامنين في الاهتمامات :)

معك حق في هذه النقطة :lol:

أشكرك أخي رامي ، بالنسبة لموضوع الأخ عيسى كان تحت عنوان نظره على Threads in Java, Ooh !!

الرابط :/index.php?showtopic=125069

ولكنه أغلق وأنا عفوا لا أعلق وربما قلت في البداية أعقب ولكن قصدي هو أني وددت المشاركة فيه، لأن الموضوع أعجبني

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

بالنسبة للترجمة للإنجليزي توجد فقط les procedures externes=External procedures والباقي مترجم في الرد رقم 6 من الموضوع.حول تعليقات السانكونايزد متودس

سأشرح المتود tEVA(int id)يستدعيها أي طالب id يود الإنتقال من E إلى A id عن طريق الباب 1 يقوم بمايلي:

NPA : عدد الطلبة بالقاعةA يزيد ب1

NAEnEntre: عدد الطلبة الداخلين من E to A يزيد ب1

فائدة الشرط تكمن في الحد من الدخول لأكثر من 10 بالقاعة A وذلك إذا كانNPA==10

أما الشرط (NAEnEntre==9)&&(NPB==5) فتمنع حدوث deadlock = interblocage

إذن إذا تحقق أحد الشرطين يبقى الطالب في حالة انتظار"بالتعليمةwait() " إلى أن يسمح له من طرف آخر خرج خارجا أو دخل للقاعة B "وذلك بالتعليمة notify()"

يتبع...

تم تعديل هذه المشاركة بواسطة asminf في 8 يناير 2009 في 15:59

#14

موضوع جميل جداً أخت أسماء

فقط أحببت أن أضيف أن جافا تحتوي على آلية Semaphore

وكنت قد ذكرت ذلك في لمحة جافاوية 7

وعلى الأغلب هذه الفئة تستخدم Monitor بشكل التفافي

على كل حال مناقشة ثرية جداُ

وأحببت أسلوب الأخت أسماء في التحليل والعرض

اتساءل هل تحبين أن أدمج الموضوع مع موضوع الأخ عيسى

أم أضيف له رابط هناك

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#15

السلام عليكــم ورحمـة الله وبركاتــه

أشكرك جدا أخي علاء على ردك ورأيك بالموضوع

بالنسبة ل السيمافور في الجافا أضنه أضيف ابتداءمن jdk1.5.0"معلومة مرت علي"

ولكن لا يعني هذا أنه لم يستخدم قبل ذلك فيمكن انشاء كلاس سيمافور باستخدام المونيتور

لقد رأيت لمحة جافاوية 7

وبصراحة فيها معلومات جديدة علي لأني لا أعلم عن الدوال المعتمدة للسيمافور في الجافا من قبل مثلا acquire();

اقتباس
اتساءل هل تحبين أن أدمج الموضوع مع موضوع الأخ عيسى

أم أضيف له رابط هناك

أشكرك على تخييري وطلب رأيي ، أفضّل دمجه لكي يفيد أكثر.

وما تراه أفضل للمنتدى افعله لا بأس بذلك

أشكرك جدا على اهتمامك بالموضوع.

التتمة تأتي لاحقا ...

النصــر لغـــزة

#16

السلام عليكــم ورحمـة الله وبركاتــه

سأكمل اليوم باقي المتودس الخاصة بالمونيتر salle

-المتود التي توفر عملية الإنتقال للطلبة من القاعة A إلى القاعة B

  1.  
  2. public synchronized void tAVB(int id) {
  3. while(NPB==5) try{wait()}catch(Interrupted
    Exception e){}
  4. NPA--
  5. NAEnEntre--
  6. NPB++
  7.  
  8. System.out.println("L'etudiant n°= "+id+
  9. " [A_B] Nbr dans A "+ NPA+" NAEnEntre dans A " +NAEnEntre+" Nbr dans B "+ NPB)
  10. notifyAll()
  11. }
  12.  
  13.  

الشرح: للدخول للقاعة B يجب أن نتأكد من عدم امتلائها" 5طلبة "وإلا يبقى الطالب في حالة انتظار الإشارة من أحد الطلبة الآخرين ، من هم؟ منطقيا إذا انهى طالب ما أشغاله في B توجه لA يلزمه اعطاء الضوء الأخضرب Notify للطالب الذي مل الإنتظار

بالنسبة للإنقاص والزيادة للمتغيرات الممثلة لعدد الطلبة بكل قاعة يبدو مفهوما.

-للإنتقال منB إلى A -وأخيرا طريق العودة- يترتب مايلي:

  1.  
  2. public synchronized void tBVA(int id) {
  3. while(NPA==10) try{wait()
    }catch(InterruptedException e){}
  4. NPB--
  5. NPA++
  6.  
  7. System.out.println("L'etudiant n°= "+ id +
  8. " [b_A] Nbr dans A "+ NPA+" NAEnEntre dans A "+NAEnEntre+" Nbr dans B "+ NPB)
  9. notifyAll()
  10. }
  11.  
  12.  

طريق العودة يبدو سهل هنا، أضن لا داعي لللشرح أكثر سوى أن المتغير NAEntree قد اختفى

لماذا؟ بالتأكيد لأنه خاص بالطلبة الداخلين من الوسط الخارجي لA ولم يدخلوا بعد ل B

Notifyall هنا تحرر الطلبة المنتظرين الدخول إلى B

-للخروج من A للوسط الخارجي هذا سهل فقط:

  1.  
  2. public synchronized void tAVE(int id){
  3. NPA--
  4.  
  5. System.out.println("L'etudiant n°= "+id+
  6. " [A_E] Nbr dans A "+NPA +" NAEnEntre dans A "+NAEnEntre+" Nbr dans B "+NPB)
  7. notifyAll()
  8. }
  9.  
  10.  

نلاحظ هنا لا شرط فالحرية للخروج، وnotifyall هنا تسمح بتحرير الطلبة المنتظرين للدخول لA إما من الوسط الخارجي أو B

وأخيرا اكتملت المونيتور وبقي الجزء المتحرك الذي يستخدم هذه المنيتور لتنظيم أعماله ألا وهو أي أنستنس من الكلاس Etudiant extends Thread

التتمة لاحقا...

النـــــصر لغــــــزة

#17

السلام عليكــم ورحمـة الله وبركاتــه

إن الهدف من المسألة هو ضمان التعاون والتنافس بين الطلبة لأداء مهامهم بالقاعة وبدون اخلال بشروط القاعة أو الإصطدام deadlockفيما بينهم.

كل طالب كما ذكرت سابقا يقوم بمايلي:

1-البقاء خارجا لمدة معينة.

2-الدخول للقاعة A"الباب 1"

3-البقاء في القاعة A مدة معينة.

4-الإنتقال من A للقاعة B"الباب 2"

5-البقاء في القاعة B لمدة معينة.

6-الإنتقال من B للقاعة A"الباب 3"

7-البقاء في القاعة A لمدة معينة.

8-الخروج خارجا "الباب 4"

عمليات الدخول والخروج المجسدة بالنقاط:2،4،6،8 يجب كما قلنا أن تتم in mutual exclusion وهذا يتم باستدعاء الأربع متود للمونيتور salle

أما بقية النقاط فهي متشابهة والتي تعني عمل آخر ما ونمثله مثلا بالمتود napping()

فيمكن وضعها بالمونيتر:

  1.  
  2. //، sleep method استدعاء هذه المتود يعني اجراء عمل ما نستخدم هنا
  3. public static void napping(){
  4. int sleeptime = (int)(5*Math.random())
  5. try{Thread.sleep(sleeptime*1000)}
  6. catch (InterruptedException e){}
  7. }
  8.  

الآن هاهو الكلاس Etudiant:

  1.  
  2. public class Etudiant extends Thread{
  3.  
  4. public Etudiant(Salle salle,int identity){
  5. this.salle=salle
  6. this.identity=identity
  7.  
  8. }
  9.  
  10. public void run(){
  11.  
  12.  
  13. //while(true){
  14. salle.napping()//البقاء خارجا لمدة معينة
  15. salle.tEVA(identity)
  16.  
  17. salle.napping()//البقاء في القاعة A مدة معينة.
  18. salle.tAVB(identity)
  19.  
  20. salle.napping()//البقاء في القاعة B لمدة معينة.
  21. salle.tBVA(identity)
  22.  
  23. salle.napping()//البقاء في القاعة A لمدة معينة.
  24. salle.tAVE(identity)
  25.  
  26. //}
  27.  
  28. }
  29. Salle salle
  30. int identity
  31. }
  32.  

إن المتود run() ضرورية لعمل أي ثريدفعلى مستواها يعرف عمله، ولكن تشغيل الثريد يتم ب start() methodالتي تستخدم من طرف كل أنستنس للثريد

الآن يبقى الكلاس ماين ويمكن وضعه بالكلاس Etudiant أو بكلاس منفصل كمايلي:

  1.  
  2. public class EtudiantsTraverser{
  3.  
  4. static final int NumEtud=30
  5.  
  6. public static void main(String[]args){
  7.  
  8. Salle s= new Salle()
  9. Etudiant[] etudiant = new Etudiant[NumEtud]
  10.  
  11. for(int i=0i< NumEtud i++){
  12. etudiant = new Etudiant(s,i)
  13. etudiant.start() }
  14. }
  15. }
  16.  

وهنا اخترنا 30 طالب مرة واحدة. وبعدها يبدأ العمل.

الحل المعطى جد سهل ويبين فقط كيفية استعمال المونيتور في الجافا لضمان التزامن بين الثريدس .

كي تتوضح الأمور أكثر سيكون معنى الكونكرنسي مابين الثريدس واضح وملموس باستخدام Animation and graphisme

وهناك سيكون تجسيد المثال رائع..

فمن يحاول..

النـــــــصر لغــــزة

مواضيع مشابهة