مقدمة حالة Java Thread مع مثال - دورة حياة الخيط
نشرت: 2019-01-11
الدول الخيط
يوضح الرسم البياني التالي الحالات المختلفة التي يمكن أن يكون فيها مؤشر ترابط Java في أي وقت خلال حياته وأي استدعاءات الطريقة التي تتسبب في الانتقال إلى حالة أخرى. هذا المخطط ليس رسمًا تخطيطيًا كاملًا للحالة المحدودة ، ولكنه بالأحرى نظرة عامة على الجوانب الأكثر إثارة للاهتمام والأكثر شيوعًا لحياة الخيط.
أنت في المكان الصحيح إذا كان لديك أي من المهام التالية:
- دورة حياة الخيط في جافا
- دورة الحياة وحالات الخيط في Java
- فهم حالات Java Thread
ما تبقى من هذه الصفحة يناقش Thread's life cycle
حيث حالته.

موضوع جديد
تقوم العبارة التالية بإنشاء مؤشر ترابط جديد ولكن لا تبدأ تشغيله وبالتالي ترك مؤشر الترابط في الحالة المسماة "مؤشر ترابط جديد" في الرسم التخطيطي.
1 |
Thread myThread = new MyThreadClass ( ) ; |
عندما يكون مؤشر ترابط في حالة مؤشر ترابط New Thread
، فهو مجرد كائن مؤشر ترابط فارغ. لم يتم تخصيص موارد النظام لذلك حتى الآن. وهكذا عندما يكون الخيط في هذه الحالة ، يمكنك فقط بدء الخيط أو إيقافه ؛ استدعاء أي طريقة أخرى إلى جانب start()
أو stop()
عندما يكون الموضوع في هذه الحالة لا معنى له ويسبب IllegalThreadStateException.
قابل للتشغيل
الآن ضع في اعتبارك هذين السطرين من التعليمات البرمجية:
1 2 |
Thread myThread = new MyThreadClass ( ) ; myThread . start ( ) ; |
تقوم طريقة start()
بإنشاء موارد النظام اللازمة لتشغيل مؤشر الترابط ، وجدولة مؤشر الترابط للتشغيل ، واستدعاء طريقة run()
. في هذه المرحلة يكون الخيط في حالة "قابل للتشغيل". تسمى هذه الحالة "قابل للتشغيل" بدلاً من "قيد التشغيل" لأن مؤشر الترابط قد لا يكون قيد التشغيل بالفعل عندما يكون في هذه الحالة. تحتوي العديد من أجهزة الكمبيوتر على معالج واحد مما يجعل من المستحيل تشغيل كافة خيوط التشغيل "Runnable" في نفس الوقت.
لذلك ، يجب أن يقوم نظام Java runtime بتنفيذ مخطط جدولة يشارك المعالج بين جميع مؤشرات الترابط "Runnable". ومع ذلك ، بالنسبة لمعظم الأغراض ، يمكنك التفكير في حالة "Runnable" على أنها "قيد التشغيل" ببساطة. عندما يكون الموضوع قيد التشغيل - إنه "قابل للتشغيل" وهو الخيط الحالي - يتم تنفيذ التعليمات الموجودة في run()
بالتتابع.
غير قابل للتشغيل
يدخل الخيط في الحالة Not Runnable
عند وقوع أحد هذه الأحداث الأربعة:
- شخص ما يسميها طريقة
suspend()
- شخص ما يسميها طريقة
sleep()
- يستخدم الخيط طريقة
wait()
الخاصة به لانتظار متغير شرط - مؤشر الترابط يحظر الإدخال / الإخراج.
على سبيل المثال ، الخط الغامق في مقتطف الشفرة هذا
1 2 3 4 5 6 |
Thread myThread = new MyThreadClass ( ) ; myThread . start ( ) ; try { myThread . sleep ( 10000 ) ; } catch ( InterruptedException e ) { } |
يضع myThread
في وضع السكون لمدة 10 ثوانٍ (10000 مللي ثانية). خلال تلك الثواني العشر ، حتى لو أصبح المعالج متاحًا ، فلن يعمل myThread
. بعد مرور 10 ثوانٍ ، يصبح myThread
"قابل للتشغيل" مرة أخرى والآن إذا أصبح المعالج متاحًا ، فسيتم تشغيل myThread
.
لكل "مداخل" إلى حالة "غير قابل للتشغيل" المذكورة أعلاه ، هناك مسار هروب محدد ومميز يعيد مؤشر الترابط إلى حالة "قابل للتشغيل". يعمل طريق الهروب فقط مع "المدخل" المقابل له. على سبيل المثال ، إذا تم وضع مؤشر ترابط في وضع السكون ، فيجب أن ينقضي العدد المحدد من المللي ثانية قبل أن يصبح الخيط "قابل للتشغيل" مرة أخرى. استدعاء resume()
على خيط نائم ليس له أي تأثير.
يشير ما يلي إلى مسار الهروب لكل مدخل إلى حالة "غير قابل للتشغيل".

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

متوفى
يمكن أن يموت الخيط بطريقتين: إما لأسباب طبيعية ، أو بالقتل (إيقاف). يموت الخيط بشكل طبيعي عندما تخرج طريقة run()
بشكل طبيعي. على سبيل المثال ، حلقة while
في هذه الطريقة هي حلقة محدودة - ستتكرر 100 مرة ثم تخرج.
1 2 3 4 5 6 7 |
public void run ( ) { int i = 0 ; while ( i < 100 ) { i ++ ; System . out . println ( "i = " + i ) ; } } |
سيموت الخيط باستخدام طريقة run()
هذه بشكل طبيعي بعد الحلقة وتكتمل طريقة run()
.
يمكنك أيضًا قتل خيط في أي وقت عن طريق استدعاء طريقة stop()
الخاصة به. هذا مقتطف الشفرة.
1 2 3 4 5 6 7 |
Thread myThread = new MyThreadClass ( ) ; myThread . start ( ) ; try { Thread . currentThread ( ) . sleep ( 10000 ) ; } catch ( InterruptedException e ) { } myThread . stop ( ) ; |
ينشئ ويبدأ myThread
ثم يضع الخيط الحالي في وضع السكون لمدة 10 ثوانٍ. عندما يستيقظ الخيط الحالي ، فإن السطر الغامق في مقطع الرمز يقتل myThread
.
تقوم طريقة stop()
بإلقاء كائن ThreadDeath على مؤشر الترابط لقتله. وهكذا عندما يتم قتل خيط بهذه الطريقة فإنه يموت بشكل غير متزامن. سيموت مؤشر الترابط عندما يتلقى بالفعل استثناء ThreadDeath.
IllegalThreadStateException
يطرح نظام وقت التشغيل IllegalThreadStateException عند استدعاء طريقة على مؤشر ترابط ولا تسمح حالة مؤشر الترابط هذا باستدعاء هذا الأسلوب. على سبيل المثال ، يتم طرح IllegalThreadStateException عند استدعاء Suspend suspend()
على مؤشر ترابط غير "Runnable".
كما هو موضح في الأمثلة المختلفة من سلاسل العمليات حتى الآن في هذا الدرس ، عندما تستدعي طريقة خيط يمكن أن تطرح استثناءًا ، يجب عليك إما التقاط الاستثناء ومعالجته ، أو إعلان أن طريقة الاستدعاء تطرح الاستثناء غير المكتسب.
طريقة isAlive ()
وكلمة أخيرة عن حالة الخيط: تشتمل واجهة البرمجة لفئة Thread على طريقة تسمى isAlive()
. ترجع isAlive()
صحيحًا إذا تم بدء تشغيل مؤشر الترابط ولم يتم إيقافه. وبالتالي ، إذا كان أسلوب isAlive()
يعيد القيمة false ، فأنت تعلم أن الخيط إما "New Thread" أو "Dead".
إذا أعادت طريقة isAlive()
true ، فأنت تعلم أن الخيط إما "Runnable" أو "Not Runnable". لا يمكنك التفريق بين "موضوع جديد" وخيط "ميت" ؛ ولا يمكنك التفريق بين سلسلة محادثات "Runnable" وخيط "Not Runnable".
أثناء البحث في أمثلة الخيوط المعقدة ، وجدت هذا البرنامج التعليمي الرائع حقًا على الشبكة. يجب على الجميع قراءة هذا بعناية.