logo

دورة حياة الخيط (حالات الخيط)

في Java، يوجد مؤشر الترابط دائمًا في أي من الحالات التالية. هذه الدول هي:

  1. جديد
  2. نشيط
  3. محظور / في انتظار
  4. الانتظار المحدد
  5. تم إنهاؤه

شرح حالات الموضوع المختلفة

جديد: كلما تم إنشاء مؤشر ترابط جديد، فهو دائمًا في الحالة الجديدة. بالنسبة لسلسلة المحادثات في الحالة الجديدة، لم يتم تشغيل التعليمات البرمجية بعد، وبالتالي لم يبدأ تنفيذها.

نشيط: عندما يستدعي خيط طريقة start()، فإنه ينتقل من الحالة الجديدة إلى الحالة النشطة. تحتوي الحالة النشطة على حالتين بداخلها: إحداهما هي قابل للتشغيل ، والآخر هو جري .

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

محظور أو في انتظار: عندما يكون الخيط غير نشط لفترة من الوقت (ليس بشكل دائم)، فإما أن يكون الخيط في حالة محظورة أو في حالة الانتظار.

على سبيل المثال، قد يرغب أحد الخيوط (لنفترض أن اسمه A) في طباعة بعض البيانات من الطابعة. ومع ذلك، في الوقت نفسه، يستخدم الخيط الآخر (دعنا نقول اسمه B) الطابعة لطباعة بعض البيانات. لذلك، يجب أن ينتظر مؤشر الترابط A حتى يستخدم مؤشر الترابط B الطابعة. وبالتالي، يكون الخيط A في حالة الحظر. الخيط في الحالة المحظورة غير قادر على تنفيذ أي تنفيذ وبالتالي لا يستهلك أبدًا أي دورة من وحدة المعالجة المركزية (CPU). ومن ثم، يمكننا القول أن الخيط A يظل خاملاً حتى يقوم برنامج جدولة الخيط بإعادة تنشيط الخيط A، وهو في حالة الانتظار أو المحظورة.

عندما يستدعي الخيط الرئيسي طريقة join()، يُقال أن الخيط الرئيسي في حالة الانتظار. ثم ينتظر الخيط الرئيسي حتى تكمل الخيوط الفرعية مهامها. عندما تكمل الخيوط الفرعية وظيفتها، يتم إرسال إشعار إلى السلسلة الرئيسية، والتي تنقل السلسلة مرة أخرى من الانتظار إلى الحالة النشطة.

إذا كان هناك الكثير من سلاسل الرسائل في حالة الانتظار أو المحظورة، فمن واجب برنامج جدولة السلاسل تحديد الخيط الذي يجب اختياره وأي الخيط الذي سيتم رفضه، ثم يتم منح الخيط المختار الفرصة للتشغيل.

الانتظار الزمني: في بعض الأحيان يؤدي الانتظار إلى المجاعة. على سبيل المثال، قام مؤشر ترابط (اسمه A) بإدخال القسم الحرج من الكود وليس على استعداد لمغادرة هذا القسم الحرج. في مثل هذا السيناريو، يجب على خيط آخر (اسمه B) الانتظار إلى الأبد، مما يؤدي إلى المجاعة. لتجنب مثل هذا السيناريو، يتم إعطاء حالة انتظار محددة التوقيت للخيط B. وبالتالي، يقع الخيط في حالة الانتظار لفترة زمنية محددة، وليس إلى الأبد. أحد الأمثلة الحقيقية على الانتظار المحدد بوقت هو عندما نقوم باستدعاء طريقة السكون () في مؤشر ترابط معين. تضع طريقة السكون () مؤشر الترابط في حالة الانتظار المحددة بوقت. بعد انتهاء الوقت، يستيقظ الخيط ويبدأ تنفيذه من الوقت الذي غادر فيه سابقًا.

تم إنهاؤه: يصل مؤشر الترابط إلى حالة الإنهاء للأسباب التالية:

  • عندما ينتهي الخيط من مهمته، فهو موجود أو ينتهي بشكل طبيعي.
  • إنهاء غير طبيعي:يحدث ذلك عند بعض الأحداث غير العادية مثل الاستثناء غير المعالج أو خطأ التجزئة.

يعني الخيط المنتهي أن الخيط لم يعد موجودًا في النظام. بمعنى آخر، الخيط ميت، ولا توجد طريقة يمكن من خلالها إعادة إحياء الخيط الميت (نشط بعد القتل).

يوضح الرسم البياني التالي الحالات المختلفة المشاركة في دورة حياة الخيط.

دورة حياة موضوع جافا

تنفيذ حالات الموضوع

في Java، يمكن للمرء الحصول على الحالة الحالية لسلسلة المحادثات باستخدام الموضوع.getState() طريقة. ال java.lang.Thread.State توفر فئة Java الثوابت ENUM لتمثيل حالة مؤشر الترابط. وهذه الثوابت هي:

سلسلة في ج
 public static final Thread.State NEW 

إنه يمثل الحالة الأولى للخيط وهي الحالة الجديدة.

 public static final Thread.State RUNNABLE 

إنه يمثل الحالة القابلة للتشغيل. ويعني أن مؤشر الترابط ينتظر في قائمة الانتظار للتشغيل.

 public static final Thread.State BLOCKED 

إنه يمثل الحالة المحظورة. في هذه الحالة، ينتظر الخيط الحصول على القفل.

 public static final Thread.State WAITING 

إنه يمثل حالة الانتظار. سينتقل مؤشر الترابط إلى هذه الحالة عندما يستدعي طريقة Object.wait() أو طريقة Thread.join() بدون مهلة. هناك مؤشر ترابط في حالة الانتظار ينتظر مؤشر ترابط آخر لإكمال مهمته.

 public static final Thread.State TIMED_WAITING 

وهو يمثل حالة الانتظار المحددة بوقت. الفرق الرئيسي بين الانتظار والانتظار المحدد بوقت هو ضيق الوقت. الانتظار ليس له قيود زمنية، في حين أن الانتظار المحدد بوقت له قيود زمنية. يصل مؤشر الترابط الذي يستدعي الطريقة التالية إلى حالة الانتظار المحددة بوقت.

  • ينام
  • الانضمام مع المهلة
  • انتظر مع المهلة
  • parkUntil
  • com.parkNanos
 public static final Thread.State TERMINATED 

إنه يمثل الحالة النهائية لسلسلة الرسائل التي تم إنهاؤها أو ميتة. الخيط المنتهي يعني أنه أكمل تنفيذه.

برنامج جافا لإظهار حالات الموضوع

يعرض برنامج Java التالي بعض حالات الخيط المحددة أعلاه.

اسم الملف: ThreadState.java

 // ABC class implements the interface Runnable class ABC implements Runnable { public void run() { // try-catch block try { // moving thread t2 to the state timed waiting Thread.sleep(100); } catch (InterruptedException ie) { ie.printStackTrace(); } System.out.println('The state of thread t1 while it invoked the method join() on thread t2 -'+ ThreadState.t1.getState()); // try-catch block try { Thread.sleep(200); } catch (InterruptedException ie) { ie.printStackTrace(); } } } // ThreadState class implements the interface Runnable public class ThreadState implements Runnable { public static Thread t1; public static ThreadState obj; // main method public static void main(String argvs[]) { // creating an object of the class ThreadState obj = new ThreadState(); t1 = new Thread(obj); // thread t1 is spawned // The thread t1 is currently in the NEW state. System.out.println('The state of thread t1 after spawning it - ' + t1.getState()); // invoking the start() method on // the thread t1 t1.start(); // thread t1 is moved to the Runnable state System.out.println('The state of thread t1 after invoking the method start() on it - ' + t1.getState()); } public void run() { ABC myObj = new ABC(); Thread t2 = new Thread(myObj); // thread t2 is created and is currently in the NEW state. System.out.println('The state of thread t2 after spawning it - '+ t2.getState()); t2.start(); // thread t2 is moved to the runnable state System.out.println('the state of thread t2 after calling the method start() on it - ' + t2.getState()); // try-catch block for the smooth flow of the program try { // moving the thread t1 to the state timed waiting Thread.sleep(200); } catch (InterruptedException ie) { ie.printStackTrace(); } System.out.println('The state of thread t2 after invoking the method sleep() on it - '+ t2.getState() ); // try-catch block for the smooth flow of the program try { // waiting for thread t2 to complete its execution t2.join(); } catch (InterruptedException ie) { ie.printStackTrace(); } System.out.println('The state of thread t2 when it has completed it's execution - ' + t2.getState()); } } 

انتاج:

 The state of thread t1 after spawning it - NEW The state of thread t1 after invoking the method start() on it - RUNNABLE The state of thread t2 after spawning it - NEW the state of thread t2 after calling the method start() on it - RUNNABLE The state of thread t1 while it invoked the method join() on thread t2 -TIMED_WAITING The state of thread t2 after invoking the method sleep() on it - TIMED_WAITING The state of thread t2 when it has completed it's execution - TERMINATED 

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