تمامًا كما يولد الناس، ويكبرون، ويمرضون، ويموتون، يجب أن تمر الخيوط أيضًا بأربع حالات مختلفة: البدء (الانتظار)، والجري، والتعليق، والتوقف. يمكن التحكم في هذه الحالات الأربع من خلال الأساليب الموجودة في فئة Thread. الطرق المتعلقة بهذه الحالات الأربع في فئة Thread موضحة أدناه.
// تعليق وتنشيط المواضيع
استئناف الفراغ العام () // غير مستحسن للاستخدام
تعليق الفراغ العام () // غير مستحسن للاستخدام
نوم الفراغ الثابت العام (مللي طويل) ؛
نوم الفراغ الثابت العام (مللي طويل، عدد صحيح من النانو)؛
// إنهاء الموضوع
توقف الفراغ العام () // غير مستحسن للاستخدام
مقاطعة الفراغ العام ()؛
// الحصول على حالة الموضوع
المنطقية العامة isAlive();
يتم مقاطعة المنطق المنطقي العام () ؛
تمت مقاطعة منطقية ثابتة عامة () ؛
// طريقة الانضمام
انضمام الفراغ العام () يلقي InterruptedException؛
لا ينفذ الخيط التعليمات البرمجية في طريقة التشغيل مباشرة بعد إنشائها، ولكنه في حالة انتظار. عندما يكون الخيط في حالة الانتظار، يمكنك تعيين سمات مختلفة للخيط من خلال أساليب فئة الخيط، مثل أولوية الخيط (setPriority)، واسم الخيط (setName)، ونوع الخيط (setDaemon).
عندما يتم استدعاء طريقة البدء، يبدأ الخيط في تنفيذ التعليمات البرمجية في طريقة التشغيل. يدخل الخيط في حالة التشغيل. يمكنك استخدام أسلوب isAlive لفئة Thread لتحديد ما إذا كان مؤشر الترابط قيد التشغيل. عندما يكون الخيط في حالة التشغيل، يُرجع isAlive صحيحًا. عندما يُرجع isAlive خطأ، قد يكون الخيط في حالة الانتظار أو في حالة التوقف. يوضح التعليمة البرمجية التالية التبديل بين الحالات الثلاث لإنشاء مؤشر الترابط، والتشغيل والإيقاف، وإخراج قيمة الإرجاع المقابلة isAlive.
تقوم دورة حياة الفئة العامة بتمديد الموضوع
{
تشغيل الفراغ العام ()
{
كثافة العمليات ن = 0؛
بينما ((++n) < 1000);
}
يلقي الفراغ الرئيسي العام (String[] args) استثناءً
{
LifeCycle thread1 = new LifeCycle();
System.out.println("isAlive: " + thread1.isAlive());
Thread1.start();
System.out.println("isAlive: " + thread1.isAlive());
thread1.join(); // انتظر حتى ينتهي مؤشر الترابط thread1 قبل متابعة التنفيذ
System.out.println("انتهى الموضوع 1!");
System.out.println("isAlive: " + thread1.isAlive());
}
}
نتيجة تشغيل الكود أعلاه:
بمجرد أن يبدأ الخيط في تنفيذ طريقة التشغيل، فلن يخرج حتى تكتمل طريقة التشغيل. ومع ذلك، أثناء تنفيذ مؤشر الترابط، هناك طريقتان يمكن استخدامهما لإيقاف تنفيذ مؤشر الترابط مؤقتًا. هاتان الطريقتان هما التعليق والسكون بعد استخدام التعليق لتعليق الخيط، يمكنك تنبيه الخيط من خلال طريقة الاستئناف. بعد استخدام وضع السكون لجعل الخيط في وضع السكون، يمكن أن يكون الخيط في حالة الاستعداد فقط بعد الوقت المحدد (بعد انتهاء سكون الخيط، قد لا يتم تنفيذ الخيط على الفور، ولكنه يدخل فقط في حالة الاستعداد، في انتظار جدولة النظام) .
على الرغم من أن التعليق والاستئناف يمكن أن يعلقا وينشطا سلاسل الرسائل بسهولة، إلا أن استخدام هاتين الطريقتين قد يتسبب في حدوث بعض الأشياء غير المتوقعة، لذلك تم وضع علامة على هاتين الطريقتين على أنهما مهملان (احتجاج)، مما يشير إلى أنه قد يتم حذف هاتين الطريقتين في jdk المستقبلي. الإصدارات، لذا حاول عدم استخدام هاتين الطريقتين لتشغيل المواضيع. يوضح التعليمة البرمجية التالية استخدام أساليب السكون والتعليق والاستئناف.
الطبقة العامة MyThread تمتد الموضوع
{
فئة SleepThread تمتد الموضوع
{
تشغيل الفراغ العام ()
{
يحاول
{
نوم(2000);
}
قبض (الاستثناء ه)
{
}
}
}
تشغيل الفراغ العام ()
{
بينما (صحيح)
System.out.println(new java.util.Date().getTime());
}
يلقي الفراغ الرئيسي العام (String[] args) استثناءً
{
MyThread thread = new MyThread();
SleepThread SleepThread = thread.new SleepThread();
SleepThread.start(); // ابدأ في تشغيل مؤشر الترابط SleepThread
SleepThread.join(); // تأخير سكون الموضوع لمدة ثانيتين
Thread.start();
علامة منطقية = خطأ؛
بينما (صحيح)
{
Sleep(5000); // تأخير الخيط الرئيسي لمدة 5 ثوان
علم = !علم ؛
إذا (العلم)
Thread.suspend();
آخر
Thread.resume();
}
}
}
هناك نقطتان يجب ملاحظتهما عند استخدام طريقة النوم:
1. تحتوي طريقة السكون على نموذجين مثقلين، لا يمكن لأحد النماذج المحملة بشكل زائد ضبط المللي ثانية فحسب، بل أيضًا النانو ثانية (1000000 نانو ثانية تساوي 1 مللي ثانية). ومع ذلك، فإن جهاز Java الظاهري على معظم أنظمة التشغيل الأساسية ليس دقيقًا بالنانو ثانية، لذلك، إذا تم تعيين النانو ثانية في وضع السكون، فسيأخذ جهاز Java الظاهري المللي ثانية الأقرب إلى هذه القيمة.
2. عند استخدام طريقة السكون، يجب عليك استخدام الرميات أو محاولة{…}التقاط{…}. نظرًا لأن طريقة التشغيل لا يمكنها استخدام الرميات، يمكنك فقط استخدام المحاولة{…}التقاط{…}. سيتم طرح InterruptedException عند مقاطعة مؤشر ترابط باستخدام طريقة المقاطعة (ستتم مناقشة هذه الطريقة في 2.3.3). يتم تعريف طريقة النوم على النحو التالي:
هناك ثلاث طرق لإنهاء موضوع.
1. استخدم علامة الخروج لجعل الخيط يخرج بشكل طبيعي، أي أن الخيط ينتهي عند اكتمال طريقة التشغيل.
2. استخدم طريقة الإيقاف لإنهاء مؤشر الترابط بالقوة (لا يُنصح بهذه الطريقة لأن الإيقاف، مثل التعليق والاستئناف، قد يؤدي أيضًا إلى نتائج غير متوقعة).
3. استخدم طريقة المقاطعة لمقاطعة الخيط.
1. قم بإنهاء الخيط باستخدام علامة الخروج
عند تنفيذ طريقة التشغيل، سيخرج الخيط. لكن في بعض الأحيان لا تنتهي طريقة التشغيل أبدًا. على سبيل المثال، تُستخدم سلاسل العمليات في برامج الخادم لمراقبة طلبات العميل، أو المهام الأخرى التي تتطلب معالجة دورية. في هذه الحالة، عادةً ما يتم وضع هذه المهام في حلقة، مثل حلقة while. إذا كنت تريد تشغيل الحلقة إلى الأبد، فيمكنك استخدام while(true){...} للتعامل معها. ولكن إذا كنت تريد الخروج من الحلقة أثناء شرط معين، فإن الطريقة الأكثر مباشرة هي تعيين علامة نوع منطقية، وتعيين هذه العلامة على صواب أو خطأ للتحكم في خروج الحلقة أثناء ذلك. يوجد أدناه مثال على إنهاء سلسلة رسائل باستخدام علامة الخروج.
الطبقة العامة ThreadFlag تمتد الموضوع
{
الخروج المنطقي العام المتقلب = خطأ؛
تشغيل الفراغ العام ()
{
بينما (! خروج)؛
}
يلقي الفراغ الرئيسي العام (String[] args) استثناءً
{
ThreadFlag thread = new ThreadFlag();
Thread.start();
Sleep(5000); // يتأخر الخيط الرئيسي لمدة 5 ثوانٍ
thread.exit = true; // إنهاء مؤشر الترابط
Thread.join();
System.out.println("تم خروج الموضوع!");
}
}
2. استخدم طريقة الإيقاف لإنهاء الخيط
استخدم طريقة الإيقاف لإنهاء مؤشر ترابط قيد التشغيل أو معلق بالقوة. يمكننا استخدام الكود التالي لإنهاء الموضوع:
3. استخدم طريقة المقاطعة لإنهاء مؤشر الترابط
يمكن تقسيم استخدام طريقة المقاطعة لإنهاء سلسلة رسائل إلى حالتين:
(1) الخيط في حالة محظورة، مثل استخدام طريقة السكون.
(2) استخدم while(!isInterrupted()){...} لتحديد ما إذا كان مؤشر الترابط قد تمت مقاطعته أم لا.
في الحالة الأولى باستخدام طريقة المقاطعة، ستطرح طريقة السكون استثناء InterruptedException، بينما في الحالة الثانية سيخرج مؤشر الترابط مباشرة. يوضح الكود أدناه استخدام طريقة المقاطعة في الحالة الأولى.
الطبقة العامة ThreadInterrupt تمتد الموضوع
{
تشغيل الفراغ العام ()
{
يحاول
{
النوم (50000)؛ // تأخير 50 ثانية
}
قبض على (InterruptedException ه)
{
System.out.println(e.getMessage());
}
}
يلقي الفراغ الرئيسي العام (String[] args) استثناءً
{
Thread thread = new ThreadInterrupt();
Thread.start();
System.out.println("اضغط على أي مفتاح خلال 50 ثانية لمقاطعة الخيط!");
System.in.read();
Thread.interrupt();
Thread.join();
System.out.println("لقد خرج الموضوع!");
}
}
توقف النوم
لقد خرج الموضوع!
ملاحظة: هناك طريقتان في فئة Thread لتحديد ما إذا كان سيتم إنهاء مؤشر الترابط من خلال طريقة المقاطعة. إحداهما هي الطريقة الثابتة التي تمت مقاطعتها () والأخرى هي الطريقة غير الثابتة هي الطريقة غير الثابتة (). الفرق بين هاتين الطريقتين هو أنه يتم استخدام المقاطعة لتحديد ما إذا كان مؤشر الترابط الحالي قد تمت مقاطعته، بينما يمكن استخدام isInterrupted لتحديد ما إذا كان. تمت مقاطعة المواضيع الأخرى. ولذلك، يمكن أيضًا استبدال while (!isInterrupted()) بـ while (!Thread.interrupted()).