في برنامج Java متعدد الخيوط، لن يتم الخروج من البرنامج بأكمله إلا بعد اكتمال تنفيذ كافة الخيوط. (تجدر الإشارة إلى أن تنفيذ جميع سلاسل المحادثات غير الخفية قد اكتمل؛ إذا نفذ خيط طريقة System.exit()، فسيخرج البرنامج أيضًا.) في بعض الأحيان، قد ترغب في إلغاء تنفيذ خيط، على سبيل المثال، إذا كنت تريد الخروج من البرنامج، أو تريد إلغاء مهمة قيد التنفيذ، وما إلى ذلك.
توفر Java آلية مقاطعة تسمح لنا بمقاطعة الخيط الذي نريد إنهاء تنفيذه بشكل صريح. إحدى ميزات آلية المقاطعة هي أنه يمكننا التحقق مما إذا كان مؤشر الترابط قد تمت مقاطعته ثم تحديد ما إذا كنا سنستجيب لطلب الإجهاض. يمكن لمؤشر الترابط أيضًا تجاهل طلب الإجهاض ومتابعة التنفيذ.
في هذا القسم، سيقوم نموذج البرنامج الذي قمنا بتطويره بإنشاء سلسلة رسائل، وبعد خمس ثوانٍ، استخدم آلية المقاطعة لإنهاء سلسلة الرسائل بالقوة.
تعرف عليه
اتبع الخطوات أدناه لإكمال نموذج البرنامج.
1. قم بإنشاء فئة باسم PrimeGenerator ورث فئة Thread. الرمز هو كما يلي:
انسخ رمز الكود كما يلي:
الطبقة العامة PrimeGenerator تمتد الموضوع {
2. أعد كتابة طريقة التشغيل () وأضف حلقة لا نهائية في الطريقة، وتحقق مما إذا كانت الأعداد الصحيحة الموجبة المتتالية التي تبدأ من 1 هي أرقام أولية من خلال الحساب. إذا كان الأمر كذلك، قم بالطباعة إلى وحدة التحكم. الرمز هو كما يلي:
انسخ رمز الكود كما يلي:
@تجاوز
تشغيل الفراغ العام () {
رقم طويل = 1 لتر؛
بينما (صحيح) {
إذا (isPrime(رقم)) {
System.out.printf("الرقم %d /tis Prime.", الرقم);
}
3. بعد معالجة الرقم، تحقق مما إذا كان الخيط قد تمت مقاطعته عن طريق استدعاء الأسلوب isInterrupted(). إذا كانت هذه الطريقة صحيحة، فستتم طباعة جملة على وحدة التحكم ثم يتم إنهاء تنفيذ مؤشر الترابط. الرمز هو كما يلي:
انسخ رمز الكود كما يلي:
إذا (تم المقاطعة ()) {
System.out.println("تمت مقاطعة المولد الرئيسي");
يعود؛
}
رقم++;
}
}
4. قم بتنفيذ طريقة isPrime()، والتي تُستخدم لتحديد ما إذا كانت المعلمة رقمًا أوليًا، إذا كان الأمر كذلك، فإنها تُرجع صحيحًا، وإلا فإنها تُرجع خطأ. الرمز هو كما يلي:
انسخ رمز الكود كما يلي:
/**
* تحديد ما إذا كانت المعلمة رقمًا أوليًا
*
* @param number الرقم المراد الحكم عليه
* @يعود
*/
منطقية خاصة هيPrime (رقم طويل) {
إذا (رقم <= 2) {
عودة صحيحة؛
}
لـ (int i = 2; i < number; i++) {
إذا ((عدد % ط) == 0) {
عودة كاذبة.
}
}
عودة صحيحة؛
}
5. الآن، قم بتنفيذ الفئة الرئيسية لنموذج البرنامج، والفئة الرئيسية، والطريقة الرئيسية (). الرمز هو كما يلي:
انسخ رمز الكود كما يلي:
الطبقة العامة الرئيسية {
public static void main(String[] args) {
6. قم بإنشاء كائن PrimeGenerator وابدأ الخيط. الرمز هو كما يلي:
انسخ رمز الكود كما يلي:
مهمة الموضوع = new PrimeGenerator();
Task.start();
7. انتظر خمس ثوان ثم قم بإنهاء الخيط. الرمز هو كما يلي:
انسخ رمز الكود كما يلي:
يحاول {
TimeUnit.SECONDS.sleep(5L);
} قبض على (InterruptedException e) {
printStackTrace();
}
Task.interrupt();
8. قم بتشغيل المثال وعرض النتائج.
أعرف لماذا
يوجد أدناه مقتطف مطبوع من مثال تنفيذ البرنامج. من الأحرف المطبوعة، يمكننا أن نرى كيف يقوم خيط PrimeGenerator بطباعة المعلومات وكيفية إنهاء تنفيذه عندما يكتشف أن الخيط قد تمت مقاطعته.
انسخ رمز الكود كما يلي:
الرقم 43063 هو أولي.
الرقم 43067 هو أولي.
الرقم 43093 هو أولي.
الرقم 43103 هو أولي.
الرقم 43117 هو أولي.
لقد تمت مقاطعة المولد الرئيسي
يحتوي مؤشر الترابط على وظيفة منطقية للإشارة إلى ما إذا كان قد تمت مقاطعة مؤشر الترابط. عندما يتم استدعاء أسلوب المقاطعة ()، يتم تعيينه على صحيح. تقوم طريقة isInterrupted() بإرجاع القيمة الحالية للخاصية.
لا تنتهي أبدا
يحتوي مؤشر الترابط أيضًا على طريقة للتحقق مما إذا كان مؤشر الترابط قد تمت مقاطعته: الطريقة الثابتة تمت مقاطعتها () والتي يمكنها التحقق مما إذا كان مؤشر الترابط الذي يتم تنفيذه حاليًا قد تمت مقاطعته.
انسخ رمز الكود كما يلي:
هناك فرق كبير بين طريقة isInterrupted() وطريقة المقاطعة(). لن يغير الأول قيمة خاصية ما إذا كان الخيط قد تمت مقاطعته أم لا، بينما يمكن للأخير تعيين قيمته على خطأ. Interrupted() هي طريقة ثابتة، يوصى باستخدام طريقة isInterrupted() للتطوير اليومي.
كما ذكرنا سابقًا، يمكن للخيط تجاهل طلب المقاطعة ومتابعة التنفيذ. ومع ذلك، هذه ليست النتيجة التي نريدها.
استخدام العقيدة
تمت ترجمة هذه المقالة من "Java 7 Concurrency Cookbook" (سرقها D Gua Ge باسم "مجموعة أمثلة Java7 Concurrency") ويتم استخدامها فقط كمواد تعليمية. ولا يجوز استخدامه لأية أغراض تجارية دون تصريح.
نجاح صغير
نسخة كاملة من كافة التعليمات البرمجية المستخدمة في البرنامج المثال.
الكود الكامل لفئة PrimeGenerator هو كما يلي:
الحزمة com.diguage.books.concurrencycookbook.chapter1.recipe3؛
/**
* التاريخ: 2013-09-18
* الساعة: 11:53
*/
الطبقة العامة PrimeGenerator تمتد الموضوع {
@تجاوز
تشغيل الفراغ العام () {
رقم طويل = 1 لتر؛
بينما (صحيح) {
إذا (isPrime(رقم)) {
System.out.printf("Number %d /tis Prime./n"، number);
}
إذا (تم المقاطعة ()) {
System.out.println("تمت مقاطعة المولد الرئيسي");
يعود؛
}
رقم++;
}
}
/**
* تحديد ما إذا كانت المعلمة رقمًا أوليًا
*
* @param number الرقم المراد الحكم عليه
* @يعود
*/
منطقية خاصة هيPrime (رقم طويل) {
إذا (رقم <= 2) {
عودة صحيحة؛
}
لـ (int i = 2; i < number; i++) {
إذا ((عدد % ط) == 0) {
عودة كاذبة.
}
}
عودة صحيحة؛
}
}
الكود الكامل للفئة الرئيسية
انسخ رمز الكود كما يلي:
الحزمة com.diguage.books.concurrencycookbook.chapter1.recipe3؛
import java.util.concurrent.TimeUnit;
/**
* التاريخ: 2013-09-18
*الزمن: 12:33
*/
الطبقة العامة الرئيسية {
public static void main(String[] args) {
مهمة الموضوع = new PrimeGenerator();
Task.start();
يحاول {
TimeUnit.SECONDS.sleep(5L);
} قبض على (InterruptedException e) {
printStackTrace();
}
Task.interrupt();
}
}