بسم الله الرحمن الرحيم الصلاة والسلام على رسول
الله اليوم إن شاء الله هنكمل في موضوع ال thread ..
ال multi-threading و هنحاول نُجمّل الكلام اللي احنا
قلناه المحاضرة الماضية قلت سابقا كل برامجنا بال
Java لحد اللحظة .. لحد المحاضرة الماضية كانت
بتشتغل على single process أو single task أو حتى لو
كان في عندي multi-task فكانت execution تبعهم بتنتهي
بشكل sequential مع إنه المعالجات عندها قدرة عالية
أنها تشغل بأكثر أو تشغل بشكل parallel واتفقنا إنه
في عندي أنا process-based multitasking وفي عندي
thread-based multitasking لـ process-based قلنا
شغل ال operating system إنه يشغل أكثر من
application مع بعض وقلنا لـ thread-based شغل ال
application الواحد إنه يشغل أكثر من task بشكل
متزامن وبعدين نتكلم عن الـ Multithreading بالجاوة
نقول إن ال thread بشكل عام يعني أنا الآن بشتغل في
ال application تبعي بدون عمل branching حسب عدد ال
branches اللي ممكن تكون عندي وبعد هيك شغل كله
يتجمع مرة ثانية يعني أنا فعليا جزء ال parallel أو
ال concurrent بيكون في جزء من البرنامج وهذا
التقسيمة بدها تكون حسب ما أنا قد إيش فاهم البرنامج
تبعي قد إيش الـdependency أو الـindependence الـ
independent parts موجودة في ال application تبعي
عشان أقدر أدي كل part ل thread معين وقولنا بشكل
عام ال thread لما أنا أنشئه يمر بمجموعة من ال
states أو ال thread حياته بتدخل مجموعة من ال
states new, runnable, blocked, waiting, time
waiting و terminated الـ new أنا أنشأته، بعدين
بنتقل لمرحلة ثانية اللي بينعمله run، execution،
blocked أثناء ال execution، بده resource، لكن ال
resource ده محجوز، هيعمل wait، الآن waiting هو
قاعد بيستنى task أو بيستنى result من ال thread
ثاني إنها تجهزت، terminated و time waiting، أنا
عامل له sleep، يستنى فترة زمنية محددة، ثم يشتغل
عليها و ال estate الأخيرة اللي بيسميها terminated
لما بينتهي كنت عشان أنشئ الـ thread بالـ Java و
بالـ code تبعي عندي حالتين إما بدي أعمل extend للـ
thread class يعني بدي أتورث خصائص من ال thread
class أو بدي أعمل implement للـ runnable interface
طب، هل في أفضلية للاثنين؟ هادي ولا هادي؟ مابتفرجش
كتير معايا بس بيحكمني في الاستخدام .. عفوا موضوع
ال inheritance اللي اتعلمناه في ال object oriented
أنا لما بكون في عندي class و عامل extend من super
class زي ال employee أو ال student أو ال vehicle
إلى آخره أنا ما أقدرش أروح أقوله كمان مرة extend
threads لكن بروح بقدر أقول له implement runnable
فالآن حسب الشغل أو الاتجاه اللي أنا بدي اشتغل فيه
حسب وضع ال application أو ال application اللي أنا
أعمل ال application اللي أنا بقى اشتغل فيه وقولنا
في كل الحالتين بدي أعمل override أو بدي أعمل
implementation للميثود اللي اسمها run هذا ال
example بشكل سريع اللي احنا شفناه extends thread
الـ run طبعاً تبعها ال data type تبعتها void يعني
ما في return data وهي ال execution تبعتها عشان أعمل
time waiting sleep هيها لو أنا بدي أروح أعمل
implement لل runnable نفس ال code run و برضه void
و نفس ال code السابق بدون أي مشاكل في داخل ال main
application تبعي اللي من البداية my thread واقتيت
واحد my thread و أديته الزمن و أديته اسم و حددته
priority my thread اتنين و أديته زمن و أديته اسم و
حددته priority thread تلاتة و هن ضروري إن تنتبه
إن أنا رجعت لل super class thread بينما هن كنت
بتعامل مع ال my thread اللي أنا عملت له extend و
العلاقة بينهم is A طيب و روحت في الآخرة إيش قلت له
هن ال new thread و أديته object mail الـ my
runnable اللي أنا اشتغلت عليه تمام وقلنا start
بتستدعي ال run method في كل واحد منهم و بمجرد أن ها
تبدأ الشغل تنتقل للي بعدها مابتستناش تخلص
وبهيك صار في عندي أنا multi-threading اشتغل في ال
application تبعي وقلنا كلام مهم جدا إن ماحدش بيضمن
كيف شكل ال output ليش؟ لأن كل هذا بيعتمد على ال CPU
ال CPU scheduler و dispatcher قد إيش في عنده task
قد إيش ال CPU busy قد إيش idol فبيروح بصير يعطي أو يجسم
الأوقات اللي موجودة عندنا أهم وقلنا بعد هيك أو
انتقلنا في نهاية المحاضرة تكلمنا على شغل يسميناها
ال synchronization أو ال lock على ال resources
اللي موجودة في داخل ال application تبعي يعني لو
كان في عندي data file ملف بدي أقرأ منه أو بدي أكتب
عليه إذا أنا بتكلم قراءة أو كتابة عملية القراءة
مافيش فيها مشكلة مابتستدعي إن هقنع مالك لأنه
أكثر من user ممكن يقرأ من نفس الملف بدون مشكلة لكن
المشكلة بتصير واضحة متى عند الكتابة إذا أنا بدي
أكتب على الملف فلازم أنا أغلق الملف ال thread على
فرض إنه أنا فيه عندي T1 و T2 و T3 دول الـ different
threads و بدهم يصلوا للملف هذا عشان يكتبوا عليه
طبعا أثناء ال execution فيه فرق زمني ما بينهم
مُصبوط الآن T3 وصل لمرحلة
قراءة الملف قبل أن بدنا نعمل lock لل file ال file
هذا ممكن يكون ال realist ممكن يكون ال vector ممكن
يكون أي شغل ثانية أي object ثاني موجود عندي ف أنا
بدي أروح أعمله lock ال lock كان معناته إثنين هدول هذا
لسه ما وصلش هذا وصل هيدخل في مرحلة blocked مغلق مش
هيقدر يشتغل ليش؟ لأن ال resource اللي بده إياه مشغول أو
محجوز من خلال T1 أو T3 خلص T3 وحده هيدا بيكون وصل
الآن واحد منهم فمجرد هدي يعمل release واحد منهم
هيمسك ال resource هيعمل lock والتاني هيدخل في
مرحلة ال blocked عشان أنفذ عملية ال blocked هذه في
عندي تلات حالات إما بروح باتجاه ال synchronized
method و بالـ Synchronized method أنا بدي أروح
أستخدم الـ keyword الـ keyword الموجود عندي
Synchronized في الـ definition تبعت الميثود أنا
بدي أقرأ ملف أو بدي أكتب على ملف الميثود هذه بروح
بعرفها public Synchronized public Synchronized
لاحظوا الميثود هذه مش static public Synchronized
مفهوم كلمة Synchronized هي موضوع الـ look أنه لازم
يكون فيه تزامن في التعامل مع الميثود هذه أطبقوا
Synchronized مفهومها Synchronized method بمجرد أن
ال thread الأول يعمل call لل method هذه ال method
هذه بيعمل لها look للكود اللي جاي نتبهي معايا لهذا
الشغل الآن هذا الكلام مهم بدي أرجع معاكي للمثال
السابق و أخلي ال function هذه حاضرة في ذهنك الآن
لو أنا جيت كتابة getdata file أو get data from
file اللي هي ال method تبعتنا ال execution هو
sequential ولا؟ تمام يعني هيبدأ ينفذ هنا هيجي على
ال method وينتقل جوا ال method sequential لما يخلص
يكمل اللي بعدها، بصبت؟ طيب ما هو ال code هذا مشترك
بين T1 و T2 و T3
T1 أو T3 عفوا وصل جابلهم وصل لـ method هن بمجرد
عمل call لـ method الآن شخص ساوية بيمنع أي thread
يكمل execution هذه مفهومها يكمل execution على
الكود اللي جاي لأن كله بيمر بنفس المرحلة فهذا من
هن من بداية ال calling لـ method هذه حتى نهايتها
ال function هذه إيش locked يعني كل الـ threads اللي
بيمشوا وراه قاعدين أو متأخرين عنه شوية في ال
execution لما يصل المرحلة هذه هيقفوا لحد ما ..
يصبحوا blocked لحد ما هذا يعمل release وبالتالي
متى بيخلص؟ لما يعمل return لل value المطلوب عنده
لحد ما يخلص كل ال function فيها ميزة كويسة إنها
بتحافظ على الشغل كله consistent من أول الـ
function لأخريتها أنا ضامن إن مافيش حد بيعمل
interference على الشغل اللي عندي ك thread لكن بعضها
فيها عيب طب لربما السطر أو الجزئية اللي أنا بدي
أكتب فيها سطر واحد موجود هن أعمل
wait لحد ما تخلص ال function أو أحط ل threads
الثانية لحد ما تخلص ال function كل الفترة الطويلة
عادي طب أما بروح بعمل block على قدر الجزئية اللي
أنا بدي إياها وبهيك بوفر وقت على ال threads
الثانية بيبدأوا يعملوا execution في ال method لحد
ما يصلوا الجزئية المحددة ال specific بيقفوا وبهيك
بصير في عندي أفضلية أو أديت وقت أو جلّت وقت
الانتظار أو وجد لمن؟ للـ threads التانين واستفدت
بشكل أكبر مين اللي بيقرر أروح باتجاه synchronized
method ولا synchronized block؟ أنت كـ Programmer أو
System Analyst اللي هو بيحدد الفقرة وين أنا بدي
أضيفهم Synchronized Block هي جزء من الـ Function
مش بالضرورة يكون كل الـ Function Synchronized طبعًا
هذه الـ method أنا في داخل الـ method بعرف الـ
synchronized مثلًا مثل الـ try وبحدد له الـ object
اللي المفروض إيش بدي أعمل عليه أنا بدي أعمل عليه
blocked وكل الـ code اللي بدي نعمل عليه blocked
يكون في داخل الـ curly braces الخاصة بمين؟ بالـ
synchronized تبعتنا يعني هذا الـ code هيكحسب المثال
هذا هينعمله closed block يعني فعليًا أي thread
هيدخل والـ code اللي جاب له هينفذه لحد ما يصل
لمن؟ لـ synchronized block وقولنا الحالة التالتة
اللي عندنا static synchronization أن أعرف static
method تمام؟ في الـ class اللي عندي as synchronized
يعني حصي في تعريفها public static-synchronized
public-synchronized static والـ data type تبعتها
صار في عندي four modifiers موجودين من الـ method
الآن إذا أنا عرفت الـ method static عرفتها
synchronized مفهومها بمجرد أي object بغض النظر هل
الـ object هذا common مع الـ threads ولا different
threads يشتغلوا عليه بمجرد ينعمل كل الـ method هذه
كل الـ objects اللي معمولة على الـ class كل الـ
instances اللي مبنية على الـ class بنعملها Blocked
ما حدش مابدأ يشتغل، خلصنا طب هذا وهذا two
different المفروض هدول التانين جايين من نفس الـ
class هدول different classes الحل خلاص أنت معرف الـ
method اللي عندنا هنا Synchronize أو Static
Synchronization Synchronize Static Method معناته
أنت هتعمل لكطيب وبهيك كنا نهينا موضوع المحاضرة
الماضية كلها يا كما الآن اللي ضايل عنا شغلة أو
تنتين مهمات جدًا في موضوع الـ threads عشان السبت
نشتغل عمله إن شاء الله تعالى الآن في
الـ code هذا
T1, T2, T3, T4 طب لو أنا بدي أكثر من هيك بدي كله
مكتوب بالشكل هذا بيبقى اللي عارف فيهم؟ هل منطق؟ لأ
طب بدي أحطهم جوا loop بنفع أحط الصدر هذا جوا loop
من خمس iterations؟
لأ لأن كل مرة بينشي object يجيب بنفس الاسم كل مرة
بينشي object يجيب بنفس الاسم وبالتالي مش منطقية
الشغل هيك فلما بدوا يفكروا في الـ Multithreading
لك ممكن أنا أشتغل على شغلة اسمها thread pool pool
اللي هي المسبح أو البركة تمام؟ ولما أتكلم على
thread pool يعني أنا بتكلم عندي على مجموعة من الـ
threads أنا بانشئها دفعة واحدة بانشئها دفعة واحدة
الآن thread pool is an instance of executor
service وهذا الـ class هو اللي هنعتمد عليه في إنشاء
الـ threads لاحقًا تمام الـ executor services هذا
بنشئ له خمس أنواع مختلفة من الـ threads الأول
single thread executor من خلال الـ executors.new
single executor يعني بنشئ أنا إيش؟ thread واحد فقط
Cached Thread Pool إيش مفهوم الـ Cache؟ أن يكون
فيه عندي شغلاء جاهزة، مظبوط؟ أنه فيه إشي جاهز
للاستخدام، ما يروحش ينشقلي ايام جديدة لما أنا بروح
بقول له Cached Thread Pool الـ scooter هذا هيروح
ينشقلي مجموعة من الـ threads أنا بحدد عددهم وليكن
خمسة على سبيل المثال الخمسة هدول إذا أنا ما
استغلتهم تمام؟ ضمن فترة معينة اللي هي 60 second
هيروحوا الخمسة على الـ terminated state إيش يعني
هيسرّلهم؟ هيعمل لهم kill، هيموتهم، يحذفهم بمعنى آخر
يعني ممكن أنا أروح أنشق cashed thread pool من عشرة
thread وأبدأ عنده في الشغل تبعي خلال أول 60 second
ثانية استغلت فقط منهم أربعة الست التانية حينعملهم
كل ميزة وعيب في نفس الوجد ميزة أن أنا بحافظ على الـ
CPU تبعي ووضع الـ state نيحة بحيث أنه مابستغلغش أو
مابحجزش وجد أو space في الـ memory بدون فايدة هذه
الميزة العيب أن هذا بفرض عليا challenge أنا كـ
developer أن أعرف فقط thread على حسب حاجتي على حسب
حاجتي النوع التالت fixed thread pool الـ fixed
thread pool أنا بنشي عدد طبعًا الآن fixed على خلاف
cash بنشي عدد ثابت خمسة عشرة استغلت منهم ثلاثة
الباقي بيبقى اللي موجود هكذا أنت حاجزت CPU وTime و
memory space بدون usage وبالتالي في الـ Fixed
Thread Pool أنا بحدد العدد اللي أنا بديه عيبها أن
لو أنا احتجت أكبر من العدد ما أقدرش أسوي حاجة ولو
احتجت أقل بكون في عندي waste في الـ time Schedule
Thread Pool Schedule يعني أنا بدي الـ threads هتتم
إنشاءها عند فترة زمنية محددة تبع الجدول محدد Single
Thread Scheduled Pool Thread واحد لكنه يكون
Scheduled هنا نتكلم عن مجموعة وهنا نتكلم عن one
thread تعال نشوف بالمثال إيش اللي هيفرق عن الكود
السابق روحك
بالمثال اللي عندنا هنا ومثال بسيط Executer
Service
executors.new fixed thread pool يعني أنا روح
باتجاه النوع التالت fixed
thread pool معناته أنا بديش fixed number of
threads وهيكون هدول موجودين للـ task اللي بقى أنا
بدي أشتغل عليها الآن إيش قلت له؟ قد إيش العدد؟ ثلاثة
يعني أنا بس بدي الـ pool تبعتي مكونة من three
threads الـ I من واحد لخمسة هاي صار في عندي loop
في داخل الـ loop أخدت counter سميته count وعطيته
قيمة الـ I ويعني واحد، اثنين، ثلاثة، أربعة، خمسة كل
مرة هيتغير ووراها مباشرة الـ S اللي هي الـ executor
service هاي dot execute أيوة
Execute هذه بتعمل creation أو بتعمل .. بتدّي الـ
task للـ thread يعني بتنشي الـ thread وبتدّي إيش الـ
task قبعته طيب إيش الـ new runnable هذه؟
هي الـ interface اللي احنا شفناها قبل هيك سابقًا بس
الآن هذه anonymous في المثال السابق object name
ديناها اسم لما أنا روحت عملت الـ implement للـ
runnable تمام؟ الـ class تبعي my runnable أخدت منه
object هنا thread new my runnable بإمكاني كنت
أستغنى عنها ومباشرة أقول له new runnable تمام؟
ومن ثم أنا بروح على object جديد أتعامل معاه و
سمينا احنا anonymous object تمام؟ الآن صار في عندي
anonymous runnable صار
في عندي runnable object بدون اسم أنا بطلت يهمني
أجدّش عدد مجرد أحق العدد هنا وإنشي اللي بدك ياه من
الـ runnable طيب لحتى الآن الكلام general في داخل
الـ code هي implementation للـ run method اللي
احنا شوفناها سابقًا اللي هي عند الـ start بتتم عليها
الشغل مباشرة والـ execute هتوجه الـ run hand مباشرة
في داخلها كنت بعمل جملة طباعة أو بطبع في لوبة
بتعمل جملة طباعة فقط thread text الـ count اللي
أنا عرفته فوق writes كتب وقيمة الـ value تبع الـ J
اللي هي من واحد لعشرة ووراها بيعمل sleep بمقدار 100
ملي second تمام بس خلصت الـ definition تبعت الـ
execute حيِطلع error ليش؟ إيه؟ لأ هو الـ error لإنه
هذه هيك لازم تكون .. اه هي موجودة بس أنا مضيع الـ
ghost في ghost اه في ghost لازم تكون هنا طيب لأ مش
هيِطلع error لأ لأ هذا تبعت الـ main الـ four لأن
هناك جملة تانية وهم اللي ورا الـ four فهي الناس
اللي جوز أكتبهم الآن مش هيطلع error الـ ball اللي
أنا أنشأت ساعة كم thread؟ ثلاثة ثم الـ task اللي
عندي لخمسة إيش هيساوي التنين الـ two task التانيات
اللي أنشأليهم الـ executor تمام؟ يعني هو الآن اللوب
هتشتغل هتشتغل هتنفذ الخمس مرات في كل مرة كانت
بتروح تحط للـ runnable في مين؟ في الـ ball حطت الأول
والتاني والتالت الآن صار الـ ball full أنت لأ بصبوط
ساعته ثلاثة راحت كمان مرة عملت generate للرابع طب
ما فيش الوسع نحط في الـ ball بنحط في Q في الانتظار
مجرد أن أول واحد منهم يخلص يدخل الرابع وين؟ على الـ
ball والخامس وراه وهكذا هذه ميزة الـ ball دائمًا أنا
بحدد عدد معين طبعًا ليش العدد هذا؟ ليش أنا محتاج الـ
ball؟ أولًا لأن أنا ممكن أحتاج عدد الـ threads أكثر
من أني أروح أعرفهم الـ Static Threads في داخل الـ
application تبعي صار في عندي الـ General
Definition للـ Thread هذه واحد اثنين لازم أحافظ
على قدرة المعالج اللي موجود عندها و أشغل ضمن قدرته
مر عليك أي application بدون ما يسألك أو يكون محدد
ال minimum requirement سواء نزلتي office ولا
operating system ولا براوزر ولا أي حد ولا حتى IDE
للبرمجة كل system مش ممكن تكتبليك ال minimum
requirement لل system هذا أن يكون المعالج كذا ال
memory كذا و ال space كذا هذا نفس الكلام بدي
أقرأه أنا هان لما أشتغل في ال application بشكل
عام طيب هذا البرنامج أو التوجه هذا توجه عام أنت
قاعد يا دكتورة بتطبع لنا جملة طباعة هانو بس، إيش
أنا المفروض أساوي؟ تخيل إيه إنه الآن أنت عندك
array من 100 ألف element integer مليون
element، مش هخسر ولا حاجة أنا أكيد في
عندي array حجمها مليون element integer وبتدرح أجيب
ال average تبعتها ماذا أفعل؟ إذا كنت تعمل على خطوة
واحدة يعني أنك تقول له هتاخد وجهة طيب ممكن أنا
أروح أجسمهم على خمس خطوات أنا بدي أحطك في صورة كيف
ممكن أنا بدي أشتغل هنا طبعا في البداية هي القرية
تبعتي ال integer x
new integer
بغض النظر عن الـ syntax وكيف بدي أعملها
initialization زي ما بدك تسميها صارت الـ array
عندي جزء من ال application ال array جزء من ال
application وروحنا احنا ال array جزء من ال
application في داخل ال run هنا أنا عامل حسابي بدي
أعدل ال application تبعي هنا ل five threads عشان
كلهم يشتغلوا إيش بتتوقعي ممكن أسوي أنا؟ بدي أكتب
code أبدأ أجسم حجم الـ R على كل thread يعني الأول
يعني بالذنب أعمل switch case بالمناسبة مصبوط أو
بالذنب دائما أعمل iterator عشان أو عفوا counter
عشان أعرف من وين بدي يبدأ لما تكون ال I equal واحد
بدي أبدأ من وين ال thread الأول بدي أبدأ من صفر اه
يعني هدول مليون أو مائة ألف مليون يعني بتكلم على
مائتين ألف مصبوط نصيب كل واحد فيهم من واحد لـ
199999 من صفر لـ 199999 هذا نصيب ال thread الأول
التاني يدرس ال counter اللي يبدأ فيه لما يشتغل
معلوق هي نفس القرية الموجودة عند التنين تمام؟
والتالت والرابع والخامس معناته أنا بلزم نهار اما
أعمل if statement أو switch يعني switch لل count لل
count عشان أحدد جوا كل case من أين .. على الأقل الـ
pointer تبعها من أين بده يبدأ وبعد ال switch case
هذه ببدأ أروح أقوله أعمل summation هيك بده يبدأ
البرنامج تبعي يعني هيك، حرج أقوله مثلا switch ال
count case
1 ال index يساوي 0 ال index يساوي 0 وهي break خلصنا
لو كانت ال case 2 ال index يساوي 200000 مصبوط و
التالتة و لما في الآخر بخلص هروح أقول له ال sum
equals 0 for عمّال iteration الآن من أين بدأت
تبدأي؟ من عند ال index ال integer I equal ال index
إلى
الـ maximum value اللي هتضيف عليهم الـ 200 ألف
التانيات نصيبه لحد آخر واحد ال sum plus ال S plus
equal ال array اللي هي X سميناها God of I وبعد هيك
بتروح ال A بتحسبيه لل average
لأ لأ for loop واحدة ليش تكتب أكثر من for loop أنت
ال case بس عشان ياخد مين ياخد ال index و الآن بعد
هيك يبدأ كل loop بتبدأ من وين بناء على قيمة ال
index أنت بحاجة ل code واحد لمرة واحدة هذا الكلام
أنت اللي لازم تبدأ تفكر فيه لأنه حسب طبيعة ال
application هي اللي بتفرض عليكي مثلا أنا في عندي
والله عشر ملفات أحجامهم مختلفة وكل مرة أبدأ أقرأ
ملف مختلف تمام؟ طب أنا أخليهم ال thread واحد اللي
يقرأهم ولا أعمل عشرة thread كلهم يوم وكل واحد
يقرأ ملف عشرة thread ممكن ما يصيرش بحاجة لأ ان اعمل
loop تمام؟ بس أعيد ضبط تسمية ال .. أو ممكن أعمل ال
loop نفسها و أعيد ضبط اسم الملف و أضيف عليه الرقم
بس تبع ال index عشان أظل ماشية فأنت كيف بدي تكون
البرنامج غير الصورة التقليدية أو البسيطة اللي احنا
بنحن نوصلك الفكرة فيها؟ هتكون الأمور تمام طيب نرجع
لمثالنا هذا عشان نكمل في مثالنا هذا إيش اللي
هيقع؟ هيكتب ل thread ال count مثلا واحد write
واحد الآن مش ضروري مباشرة اكتب ل thread واحد write
اثنين ويمكن يكتبها ممكن لكن بعدها هتلاقي thread 2
write 1 thread 3 write 1 thread 1 write 3 thread 2
write 4 write 5 وهكذا لكن اللي هتشوفيهم هان واحد
و اثنين و ثلاثة فقط لمتى لحد ما تخلص ال loop هذه
بيكون واحد من ال threads هتخلص بتبدأ تشوف أربعة
لأنه بمجرد أنه دخلهان حاول يعمل execute ما لقيش
space في ال ball فاشرح سوا عمل pause ال counter
زاد فعمل و جفت pause وبالتالي مش حاجة يقدر يكمل أو
حطهم في ال queue فأربعة أو خمسة هتشوفيهم اتباعا
لكن بعد ما حد يخلص من هدول التلاتة اللي في الأول
الآن هذا الكلام هو
زبدة لـ threads تمام؟ و لازم احنا نحاول نفهمه بشكل
واضح في عيوب الآن العيب الأول .. العيب الأول في
حالة زي هذه أنا ما فيش عند return data عشان أقدر
أخد القيمة اللي حسبتها وهذا بتدفعني أن أروح أعرف
global variable أو أصر أخد ال value و أحطه في ال
global variable طب احنا عارفين أن ال global
variable عليها مشاكل دائما و لا يحب تستخدمها
اثنين، لو صار في عندي أي مشكلة في داخل الـ run و
أنا مش عامل try و catch، مش هقدر أشوف .. مش هكمل
و مش هعرف أي thread اللي واقف، عشان هيك، راحوا
باتجاه interface مختلف تماما عن الـ runnable راحوا
باتجاه interface مختلف تماما عن الـ runnable حقق
فيه المستن أو عالجوا فيه اللعبين اللي قلنا عليهم
ال return data و ال exception handling الآن الشغل
السابق اللي هو في المثال هذا تقريبا نفسه مع فارق
بسيط جدا أن الآن هذا بيصير callable والـ method
اسمها call بدل run بدل execute هتكون في عندي
submit وهتكون في عندي return data من نوع future
حلقة
نتكلم في التفاصيل يعني الآن ال code السابق هينضاف
عليه شغلات بسيطة تحقق أو تعالج العيبين اللي حاكينا
عليهم الأولى أن ال callable interface هو عبارة أو
استخدم generic عشان يعمل return ل data type إيش
generic؟ عام يعني بيظبط مع ال integer و بيظبط مع
ال string و بيظبط مع ال employee student .. ال
employee object و مع ال student object .. مع أي
حاجة ال executor هتنفذلي .. يوفرطلي مجموعة أو
method عشان تنفذ ال callable اللي اسمها submit
هنشوفها في ال code كمان شوية في حين سابقا مع ال
runnable اسمها execute
one طيب الـ callable بعمل return ل object من نوع
future object من نوع future أول مرة نسمع عن data
type اسمها future صح؟ أو ال future هذا هي عبارة عن
container بتحط فيه أي data type عشان هي اسمها
generic وحنشوف زي ما شوفنا مع ال array list أو مع
ال collections إيش كانت ميزة ال collections أنـها
generic بتاخد أي data types هو كانت object غلط
بتاخدش اللي غير reference data type أيوة ما بتاخد
أيوة بتاخد ال wrapper class تبع ال primitive data
تعال نشوف ال code ما ضلش فيه كلام نظر كثير اه إذا
أنا بدي ال value اللي موجودة أو اللي تم تخزينها في
ال future في عندي method اسمها get و بترجع بال
data type اللي تم إنشاء الـ future عليها تعال نشوف
ال code البسيط هذا انسيلي ال future في الأول
executor dot new single thread executor نفس ال
code اللي احنا شفناه سابقا بس كان مع thread pool
مظبوط من ثلاثة الآن إيش نوعها future و بتعمل
wrapper class لل integer واسمه F dot
كمل الـ definition هذا dot submit يعني هذا كل ياته
ال code هذا اللي هان هو عبارة لحد اللي هان هيك في
تعريف ال future اللي عندي فوق الآن احنا قلنا سابقا
execute dot execute و
كنت بدّله new runnable مظبوط؟
الآن أنا روح أدخل الـ new callable و الـ callable
بده data type تتوافق مع ال future اللي أنا بده آخد
منه ال data طيب ال callable عمل override أو جال
يعمل override للـ method اللي اسمها call ولازم
تتوافق مع نفس الـ data type تبعت الـ callable اللي
بتوافق مع الـ data type الخاصة لأن في الآخر الـ
callable هي اللي هتعمل return للـ data هيسلمها الـ
callable ويمررها لمين؟ للـ future وأنت بدك تاخد الـ
result من الـ future الآن في داخلها فقط أنا عملت
هنا مثال بسيط جدا بدي أعمل return لـ 115 اللي 23 ضرب
5 ولا تنسى إنّها حدثت إن لدي hand صارت تعمل throw
لـ exception يعني لو حدث أي exception هنا في داخل
الـ call بقى أشوفه بينما في الـ run ماكنتش مقدر أسوي
هيك شغل تمام خلصنا هذا على one thread لو أنا بدي
أعمل pool نفس الكلام ما فيش مشكلة عندي هتعمل loop
وكل واحدة هترجع بـ data type بدل الـ result الآن هاي
الـ result مش احنا اتفقنا إن الـ result اللي هترجع
فيها الـ call method هتتخزن وين؟ في الـ future هي f
.get بترجعلي بالـ data type اللي تم تخزينها وين؟ في
داخل الـ future الآن ليش حطيت integer أنا هنا؟ عادي
لأن هذا wrapper class لهذه وفيها auto boxing و
unboxing، مظبوط؟ مية لمية طيب على مثال الـ array ده
إيش المفروض إن أنا أساوي لو أنا بدي أحسب عندي
array من مليون element وبدي أساوي إيش بدي اروح
أساوي هان؟ في الـ call في داخل الـ call بدي اعمل ليه
switch case عشان أجسم كمان و يحسب و اروح أعمل
return لمين؟ للـ sum أو للـ average مش قضية كتير للـ
sum أو للـ average هيعمل return وهيروح يضيفلي
اليوم في مين؟ في الـ future بس الـ future فيها single
value هذا الآن معناته الـ future هذا بيصير عبارة عن
الـ ray بيصير عبارة عن الـ ray أو الـ ray list مظبوط؟
لأن كمان مرة أنت تتخيل إن هان عامل إحنا إيش هن؟
new single thread executor طب لأ أنا ما بديش single
thread executor بدوروح أقوله؟ الـ New Fixed Thread
Pool ما بديش واحد بدي مجموعة أنا خمسة عشان أجسمهم طب
ما هدول الخمسة New
Fixed Thread Pool خمسة
بدي
أعمل counter عشان الـ Submit تبعت عندي هنا صح؟ و
بدي أكمل اللي أنا بدي أجسم طب ما هي الـ future هذي
بدنا معاهدة في عندي five threads بدهم يشتغلوا كل
واحد له future فالحل إنّي أعمل array of futures أو
array list of future وبعد هيك أنا بروح بأخد إيش الـ
value من الـ array list أو من الـ array تبعتي لكن في
شغل مهم جدا هنا مش ضروري الـ array .. حفظك الـ
thread الأول يخلص قبل ولا لا؟ اللي بيخلص أول هو
اللي بيضيف على الـ future أو على الـ array list
بتاعة الـ future يعني الـ index الأولى في الـ array
لأول واحد بيخلص الثاني على الثاني ولا الثالث و
هكذا، مظبوط؟ وبالتالي ما فيش ضامن إيش الترتيب، بس
الشغل الوحيد اللي أنا بضمنها إن الـ value اللي في
الـ future إذا كنت بتتكلم على average، الـ average
تبع الـ average value تاع الـ future هي الـ average
للـ array كلها، وإذا كنت بتتكلم على الـ sum، الـ sum
للـ values اللي موجودة في الـ future بتمثل المجموع
تبع الـ array كلها، ومن ثم أنا بدأ أكمل حسبتي
للآخر،
حتى هذا مثال هيني أنا بأجمع نفس المثال السابق، بس
أنا كنت بدون الـ code هذاروحت جامعت وعملت return
للجامع فاتخزن وين؟ في الـ future اللي موجود عندي
ليش أنا هذا الكلام؟ عشان أوصلك لنفس المرحلة هذه
اللي أنا عملت فيها الـ loop هيها executor service
أنا أجيت هنا executor service a new single بس ما بديش
a new single هنا a new fixed thread
pool الـ future هذا هيكون عبارة عن الـ realist من
الـ future مصدورة أو لا؟ وأصلا أنا بدي أتعامل مع
الـ element أو مع العناصر اللي موجودة عندي هنا في
داخل الـ array وهذا كل اللي عندنا في موضوع الـ
threads يعني أو بين جسين هذه النقاط الأساسية
المهمة في موضوع الـ threads يوم السبت إن شاء الله
تبارك وتعالى .. إن شاء الله تكفينا الساعة ونحاول
نطبق كل الكلام ده إيش؟ بشكل عامل، نعم مرة
ثانية، إنشاء threads أكثر من؟ أكثر من 100%
A K لأ لأ ما بديش هيك تخلطي تخلطي إن كل core
هياخد thread لأ الـ thread هي هتكون الـ process للـ
core الواحد يعني أنت في الآخر الـ CPU عندك
different cores مظبوط حتى الـ core الواحد ideal مثل
الآن مين اللي بتولّى تشغيل الـ cores الـ operating
system أنت كل اللي بتسويه في الـ application بتقوليه
للـ operating system إن أنا في عندي different task
بدي أنفذها الـ operating system اللي بياخدها و
بوزعها خلص الـ core الأول هو اللي بيعطي الـ core
الثاني وبيعطي الـ core الثالث والرابع طب كل الـ
cores busy الـ task تبعتك بتخش في الـ queue تبعت الـ
operating system وبنفذها تباع لما بيجيها الدور
أما ما لكش دخل أنت ممكن تقل بـ 100 على single core
100 thread على single core إحنا هي هي بالمثال هذا
إيش عملنا؟ عملت three threads بصبت ورحت قلت له
أنا في عندي خمسة task وين الـ 1010 الأخرانيات دخلوا
في الـ weight أو في الـ Q لحد ما يخلص الـ pool يصير
فيها متسع ونفس الكلام بيصير عندك على الـ operating
system بس مش شغلك أنت اللي تعملي له management لأن
الـ operating system هو اللي بتدور عندك فأنت ما
تقارن أو ما تربط بعدد الـ thread بعدد الـ cores اللي
موجودة عندك على المعالج أي سؤال ثاني بنات؟