في القسم السابق "انقطاع الخيط" شرحنا كيفية مقاطعة الخيط قيد التنفيذ وما يجب علينا فعله للخيط حتى نتمكن من مقاطعة الخيط. بشكل عام، يمكننا استخدام آلية المقاطعة التي تم تقديمها في القسم السابق. ومع ذلك، إذا كان الخيط ينفذ خوارزمية معقدة موزعة بين طرق متعددة، أو إذا كان هناك استدعاء متكرر في استدعاء الطريقة، فيجب علينا استخدام طريقة أفضل للتحكم في انقطاع الخيط. لهذا الغرض، توفر Java InterruptedException. يمكن طرح هذا الاستثناء عند اكتشاف طلب مقاطعة ورصده في طريقة التشغيل ().
في هذا القسم، سنستخدم مؤشر ترابط للبحث عن الملفات في دليل محدد وأدلته الفرعية لتوضيح التحكم في مقاطعة مؤشر الترابط باستخدام InterruptedException.
تعرف عليه
اتبع الخطوات الموضحة أدناه لتنفيذ نموذج البرنامج.
1. قم بإنشاء فئة باسم FileSearch وقم بتنفيذ الواجهة القابلة للتشغيل. الرمز هو كما يلي:
انسخ رمز الكود كما يلي:
فئة عامة FileSearch تنفذ Runnable {
2. قم بتعريف متغيرين، أحدهما لاسم الملف المراد البحث فيه، والآخر لتهيئة الدليل المراد البحث فيه؛ وتنفيذ مُنشئ الفئة، وتهيئة المتغيرين اللذين تم الإعلان عنهما للتو باستخدام معلمات المُنشئ. الرمز هو كما يلي:
انسخ رمز الكود كما يلي:
سلسلة خاصة initPath؛
اسم ملف سلسلة خاص؛
FileSearch العام (String initPath، String fileName) {
this.initPath = initPath;
this.fileName = fileName;
}
3. قم بتنفيذ طريقة التشغيل () التي تتحقق مما إذا كان اسم الملف هو اسم المسار. إذا كان الأمر كذلك، فاتصل بأسلوب DirectoryProcess() للمعالجة. يطرح أسلوب DirectoryProcess() InterruptedException، لذلك نحن بحاجة إلى اكتشاف الاستثناء. الرمز هو كما يلي:
انسخ رمز الكود كما يلي:
@تجاوز
تشغيل الفراغ العام () {
ملف الملف = ملف جديد (initPath)؛
إذا (file.isDirectory()) {
يحاول {
دليل العملية(ملف);
} قبض على (InterruptedException e) {
System.out.printf("%s: تمت مقاطعة البحث"،
Thread.currentThread().getName());
}
}
}
في المقالة الأصلية، اسم الطريقة المذكورة هوprocessDirectory(). ومع ذلك، وفقًا للإجراء الموضح أدناه، فهذا خطأ كتابي. لذا قم بتصحيحه.
4. قم بتنفيذ طريقة DirectoryProcess(). تقرأ هذه الطريقة جميع الملفات والأدلة الفرعية الموجودة في الدليل المحدد ثم تقوم بمعالجتها. لكل دليل، تقوم هذه الطريقة بإجراء استدعاء متكرر لمعالجة الدليل المحدد بواسطة المعلمة. لكل ملف، تستدعي هذه الطريقة طريقة fileProcess(). بعد معالجة كافة الدلائل والملفات، ستتحقق هذه الطريقة مما إذا كان مؤشر الترابط قد تمت مقاطعته، وهو ما يعني استثناء InterruptedException. الرمز هو كما يلي:
انسخ رمز الكود كما يلي:
/**
* معالجة الدليل
*
* دليل الملف @param المراد معالجته
* @throws InterruptedException
*/
دليل باطلة خاصة (ملف ملف) يلقي InterruptedException {
قائمة الملف[] = file.listFiles();
إذا (فارغة!= قائمة) {
لـ (int i = 0; i < list.length; i++) {
إذا (قائمة[i].isDirectory()) {
DirectoryProcess(list[i]);
} آخر {
fileProcess(list[i]);
}
}
}
إذا (Thread.interrupt()) {
رمي InterruptedException () الجديد ؛
}
}
5. قم بتنفيذ طريقة fileProcess()، التي تقارن الملف الذي تتم معالجته باسم الملف الذي سيتم العثور عليه. إذا كانت أسماء الملفات متساوية، فسيتم طباعة رسالة إلى وحدة التحكم. يتحقق الخيط بعد ذلك لمعرفة ما إذا تمت مقاطعته، وإذا كان الأمر كذلك، فسيطرح استثناء InterruptedException. الرمز هو كما يلي:
انسخ رمز الكود كما يلي:
/**
* الملفات المعالجة
*
*ملف الملف @param المراد معالجته
* @throws InterruptedException
*/
عملية ملف باطلة خاصة (ملف ملف) تطرح InterruptedException {
إذا (file.getName().equals(fileName)) {
System.out.printf("%s : %s/n"،
Thread.currentThread().getName(),
file.getAbsolutePath());
}
إذا (Thread.interrupt()) {
رمي InterruptedException () الجديد ؛
}
}
6. الآن، قم بتنفيذ الفئة الرئيسية للمثال وقم بتنفيذ الطريقة main(). الرمز هو كما يلي:
انسخ رمز الكود كما يلي:
الطبقة العامة الرئيسية {
public static void main(String[] args) {
7. قم بإنشاء كائن FileSearch وتهيئته، ثم قم بإنشاء كائن Thread لتنفيذ المهمة. ثم، ابدأ الخيط. الرمز هو كما يلي:
انسخ رمز الكود كما يلي:
FileSearch fileSearch = new FileSearch("C://", "autoexec.bat");
موضوع الموضوع = موضوع جديد (ملف البحث)؛
Thread.start();
8. انتظر عشر ثوان ثم قم بمقاطعة الخيط. الرمز هو كما يلي:
انسخ رمز الكود كما يلي:
يحاول {
TimeUnit.SECONDS.sleep(10);
} قبض على (InterruptedException e) {
printStackTrace();
}
Thread.interrupt();
9. قم بتنفيذ المثال وعرض النتائج.
أعرف لماذا
ما يلي هو نتيجة تنفيذ مؤشر الترابط. يمكن أن نرى من الإخراج كيف يتم إنهاء تنفيذ مؤشر الترابط عندما يكتشف FileSearch أنه تمت مقاطعته.
انسخ رمز الكود كما يلي:
الموضوع-0: C:/autoexec.bat
الموضوع-0: تمت مقاطعة البحث
في هذا المثال، نستخدم استثناءات Java للتحكم في انقطاع سلسلة المحادثات. عند تشغيل المثال، يتحقق البرنامج مما إذا كان الدليل المحدد وأدلته الفرعية تحتوي على الملف الهدف. على سبيل المثال، إذا قمت بإدخال /b/c/d، فسيقوم البرنامج باستدعاء طريقة DirectoryProcess() بشكل متكرر ثلاث مرات. عندما يكتشف الخيط أنه تمت مقاطعته، سيتم طرح InterruptedException بغض النظر عن عدد الاستدعاءات المتكررة التي يتم إجراؤها، سيبدأ البرنامج في تنفيذ طريقة run().
لا تنتهي أبدا
يتم طرح استثناءات InterruptedException بشكل عام بواسطة واجهات برمجة تطبيقات Java المتزامنة، مثل طريقة السكون ().
استخدام العقيدة
تمت ترجمة هذه المقالة من "Java 7 Concurrency Cookbook" (سرقها D Gua Ge باسم "مجموعة أمثلة Java7 Concurrency") ويتم استخدامها فقط كمواد تعليمية. ولا يجوز استخدامه لأية أغراض تجارية دون تصريح.
نجاح صغير
الكود الكامل لفئة FileSearch هو كما يلي:
الحزمة com.diguage.books.concurrencycookbook.chapter1.recipe4؛
استيراد java.io.File؛
/**
* التاريخ: 2013-09-18
* الساعة: 18:21
*/
فئة عامة FileSearch تنفذ Runnable {
سلسلة خاصة initPath؛
اسم ملف سلسلة خاص؛
/**
* منشئ التهيئة
*
* @param initPath الدليل المراد البحث فيه
* @param fileName اسم الملف الذي سيتم العثور عليه
*/
FileSearch العام (String initPath، String fileName) {
this.initPath = initPath;
this.fileName = fileName;
}
@تجاوز
تشغيل الفراغ العام () {
ملف الملف = ملف جديد (initPath)؛
إذا (file.isDirectory()) {
يحاول {
دليل العملية(ملف);
} قبض على (InterruptedException e) {
System.out.printf("%s: تمت مقاطعة البحث"،
Thread.currentThread().getName());
}
}
}
/**
* معالجة الدليل
*
* دليل الملف @param المراد معالجته
* @throws InterruptedException
*/
دليل باطلة خاصة (ملف ملف) يلقي InterruptedException {
قائمة الملف[] = file.listFiles();
إذا (فارغة!= قائمة) {
لـ (int i = 0; i < list.length; i++) {
إذا (قائمة[i].isDirectory()) {
DirectoryProcess(list[i]);
} آخر {
fileProcess(list[i]);
}
}
}
إذا (Thread.interrupt()) {
رمي InterruptedException () الجديد ؛
}
}
/**
* الملفات المعالجة
*
*ملف الملف @param المراد معالجته
* @throws InterruptedException
*/
عملية ملف باطلة خاصة (ملف ملف) تطرح InterruptedException {
إذا (file.getName().equals(fileName)) {
System.out.printf("%s : %s/n"،
Thread.currentThread().getName(),
file.getAbsolutePath());
}
إذا (Thread.interrupt()) {
رمي InterruptedException () الجديد ؛
}
}
}
الكود الكامل للفئة الرئيسية
انسخ رمز الكود كما يلي:
الحزمة com.diguage.books.concurrencycookbook.chapter1.recipe4؛
import java.util.concurrent.TimeUnit;
/**
* التاريخ: 2013-09-18
* الساعة: 19:28
*/
الطبقة العامة الرئيسية {
public static void main(String[] args) {
FileSearch fileSearch = new FileSearch("C://", "autoexec.bat");
موضوع الموضوع = موضوع جديد (ملف البحث)؛
Thread.start();
يحاول {
TimeUnit.SECONDS.sleep(10);
} قبض على (InterruptedException e) {
printStackTrace();
}
Thread.interrupt();
}
}