يمكن أن تنفذ تجمعات الخيوط مهام متعددة بشكل متزامن. في بعض الأحيان ، قد نرغب في تتبع نتائج تنفيذ المهام. حتى في غضون فترة زمنية معينة ، إذا لم تكتمل المهمة ، فقد نرغب أيضًا في إلغاء تنفيذ المهام. لدعم هذه الميزة ، يوفر ThreadPoolexecutor تسمية مستقبلية لتتبع تنفيذ المهام وإلغاءها. تقدم هذه المقالة مبدأ التنفيذ في مستقبلات FutureTash.
من أجل فهم مبدأ التنفيذ بشكل أفضل لمستجمعات FutureTash ، نقدم أولاً العديد من الواجهات والهياكل الفئة المهمة ، كما هو مبين في الشكل أدناه:
يوفر ThreadPoolExecutor واجهة إرسال لتقديم المهام. يدعم إرسال واجهتين مختلفتين: Runnable و Callable. من أجل توفير واجهة خارجية موحدة ، يلتف JDK داخليًا قابلاً للاستدعاء ، ويتم تنفيذ جميعها من خلال محول RunnableAdapter. فيما يلي رمز المصدر لـ RunNableAdapter:
الفئة النهائية الثابتة RunNableAdapter <T> تنفذ المهمة القابلة للاتصال <T> {Final Runnable Task ؛ النتيجة النهائية RunNableAdapter (مهمة Runnable ، t نتيجة) {this.task = task ؛ this.result = النتيجة ؛ } t call () {task.run () ؛ نتيجة العودة }}RunnableadApter هي فئة التنفيذ القابلة للاتصال ، والتي تنفذ طريقة الاتصال. تقوم طريقة الاتصال ببساطة بالاتصال Task.Run () ثم تُرجع النتيجة ، مما يضمن أنه يجب التعامل مع الواجهة القابلة للاتصال فقط بشكل موحد داخليًا.
من خلال القسم السابق ، نعلم أن المهمة المقدمة المقدمة يتم تحويلها داخليًا إلى مهام قابلة للاستدعاء. تحقق من قيمة الإرجاع لطريقة إرسال ، وهي مستقبل. في الواقع ، هذا المستقبل هو مثال مستقبلات. من خلال هذه الحالة ، يمكن لاستدعاء طريقة GET حظر الخيط الحالي حتى يتم الانتهاء من المهمة وإعادة النتيجة.
تبدو سلسلة المكالمات بأكملها مثل هذا:
موضوع العمال -> futureTask.run () -> callable.call () -> Task.Run ()
إذا تم تقديم المهمة القابلة للاتصال ، فهناك المكالمات الثلاثة الأولى فقط.
من أجل إظهار العملية بأكملها بشكل أفضل ، سيتم استخدام الأمثلة التالية لإظهار عملية التنفيذ.
1. إرسال مهمة قابلة للاستدعاء إلى مجموعة مؤشرات الترابط (سيتم تحويل Runnable إلى قابلة للاستدعاء). في هذا الوقت ، يتم تمرير القابل للاستدعاء إلى مثيل مستقبلي ، كما هو موضح أدناه:
2. يستخدم تجمع مؤشرات الترابط مؤشر ترابط لتنفيذ مهمة FutureTask.
عملية تنفيذ المهام بسيطة نسبيا. في النهاية ، سيتم استدعاء طريقة callable.call () أو runnable.run () ، وسيتم الحصول على نتيجة ، والتي ستخزن النتيجة خاصية نتائج مثيل المهام المستقبلية ، وسيتم تعديل الحالة إلى طبيعتها ، مما يشير إلى أنه تم تنفيذ المهمة ويمكن الحصول على النتيجة.
نحن نفترض أن مؤشرات ترابط متعددة تستدعي طريقة الحصول على نفس مثيل FutureTask أثناء تنفيذ callable.call() . في هذا الوقت ، سيتم حظر هذه الخيوط وتخزينها في مكدس ، كما هو موضح في الشكل أدناه:
المواضيع 1 و 2 و 3 استدعاء طريقة FutureTask.get . نظرًا لعدم تنفيذ المهمة ، سيتم حظر جميع المواضيع الثلاثة والنعاس. هناك مكدس في مستقبلات لتخزين خيوط الانتظار. تتم الإشارة إلى المؤشر الأعلى للمكدس بواسطة FutureTask.waiters . عند تنفيذ المهمة ، ستتكرر مؤشرات الترابط في المكدس بأكمله. في هذا الوقت ، سيتم إيقاظ كل مؤشر ترابط ويمكن الحصول على نتيجة تنفيذ المهمة بنجاح (يتم تخزين نتيجة التنفيذ في FutureTask.outcome) .
يدعم FutureTask أيضًا وظيفة الإلغاء للمهام ، وكلها تنسيق مؤشرات ترابط متعددة من خلال حالة FutureTask.
واجهة FutureTask هي آلية تنفيذ توفر لنا تتبع والتحكم في تنفيذ المهام. بالمقارنة مع تجمع الخيوط نفسه ، فهو بسيط نسبيًا وأعتقد أنه ليس من الصعب فهمه.
ما ورد أعلاه هو كل محتوى هذه المقالة حول مبدأ التنفيذ لمستقبلات FutureTash في مجموعة خيوط Java. آمل أن يكون ذلك مفيدًا للجميع. يمكن للأصدقاء المهتمين الاستمرار في الرجوع إلى الموضوعات الأخرى ذات الصلة على هذا الموقع. إذا كانت هناك أي أوجه قصور ، فيرجى ترك رسالة لإشارةها. شكرا لك يا أصدقائك لدعمكم لهذا الموقع!