في تطبيق واحد تم ترحيله ، عند استدعاء طريقة ، سيتم إرجاع النتيجة فقط عند انتهاء الحساب.
السلسلة العامة downloadContents (url url) يلقي ioException {trystream input = url.openstream ()) {return ioutils.tring (input ، standardc harsets.utf_8) ؛}} // ... Final Future <strong> Contents = newContents (جديد url ("http://www.example.com") ؛
DownloadContents () تبدو غير ضارة ، ولكن يجب القيام بها لفترة طويلة. في الوقت نفسه ، من أجل تقليل التأخير ، خلال نتيجة الانتظار ، قد تحتاج إلى التعامل مع أعمال أخرى بشكل مستقل في نفس الوقت. في الماضي ، يمكنك بدء تشغيل مؤشر ترابط جديد أو انتظر النتائج (مشاركة الذاكرة ، القفل ، WAID ()/إخطار () زوج).
من خلال الوضع المستقبلي <T> ، سيتضح:
مستقبل ثابت عام <Tring> بدء التشغيل (url url) {// ...} المستقبل النهائي <string> contentsfuture = startDownload (جديد ، http: //www.example .com ")) ؛ .يحصل ()؛
سوف ندرك بدء التشغيل () ، ولن يتم حظر التحميل المستمر () ، ولكن في انتظار الاستجابة للمواقع الخارجية. على العكس من ذلك ، إذا عاد بسرعة وإرجاع كائن مستقبل خفيف الوزن <STRING>. هذا الكائن هو وعد ، لذلك يتوفر نوع السلسلة المستقبلية. بمعنى آخر ، المستقبل هو وكيل أو عبوة كائن ، وليس كائنًا مستهدفًا حقيقيًا. بمجرد اكتمال الحساب غير المتزامن ، يمكنك استخراجه. إذن ما نوع الواجهة التي يوفرها المستقبل؟
Future.get () هي الطريقة الأكثر أهمية. إنه يحظر وينتظر حتى تتوفر نتيجة الوعد ، لذلك إذا كنا بحاجة حقًا إلى هذه السلسلة ، اتصل بالطريقة GET () وانتظر. هناك أيضًا نسخة تحميل ثقيلة تقبل معلمات المهلة.
في بعض الحالات ، قد ترغب في إلقاء نظرة سراً على ما إذا كان المستقبل متاحًا. يمكن القيام بذلك من خلال ISDONE (). تخيل موقفًا ، ينتظر المستخدم بعض الحسابات غير المتزامنة.
المستقبل النهائي <String> contentsfuture = startDownloading (url جديد ("http://www.example.com") ؛ بينما (! contentsfuture.isdone ()) {assusertowail () ؛ do someComputintheMeantime () ؛} contentsfuture.get () ؛؛
أخيرًا ، يضمن محتوى Future.get () العودة فورًا دون حظره ، لأن Future.isDone () يعود صحيحًا. إذا اتبعت هذا النموذج ، فلن تكون مشغولاً في الانتظار والاتصال ISDONE () بالتناوب كل ثانية.
إلغاء المستقبل هو آخر واحد لم نغطيه. تخيل أنك تبدأ العمل غير المتزامن ويمكنك الانتظار فقط لبعض الوقت. ومع ذلك ، فأنت مواطن صالح ، يجب أن تخبر هذا الكائن المستقبلي: لم أعد بحاجة إليك ، فأنت لا تهتم. ثم يمكنك توفير الموارد عن طريق إيقاف المهام التي عفا عليها الزمن. القواعد بسيطة:
contentsfuture.cancel (True) ؛
نود جميعا إخفاء ، معلمات نوع البوير ، أليس كذلك؟ يمكن تنفيذ الإلغاء من خلال طريقتين: قبل بدء المهمة ، يتم إلغاء المعلمة الخاطئة ، بشرط أنه قبل أن يتم التعبير عن نتائج المستقبل ، يبدأ الحساب. بمجرد أن يتم تشغيل callable.call () إلى النصف ، نريد أن ندعه ينتهي. هل تعتقد أن هذا جيد؟ الظواهر أولئك الذين يرميون المقاطعات ، والطريقة سيئة السمعة ، مثل thread.sleep () ، object.wait () ، conition.await () ، وما إلى ذلك ، حتى لو كنت محظورًا في هذه الطريقة ويقرر بعض الأشخاص إلغاء مكالمتك ، سوف يقومون بلا شك برمي الانقطاع ، ويرسلون شخصًا ما لمقاطعة مهمة العملية الحالية.
لذلك نحن نفهم الآن ماهية المستقبل --- عنصر نائب ، يمكنك الحصول على الكائن المستهدف في المستقبل. تماما مثل السيارة ، لا يوجد مفتاح للتصنيع. ولكن كيف يمكنك الحصول على مثيل للمستقبل في التطبيق؟ الموارد الأكثر شيوعًا هما تجمعات الخيوط والطرق غير المتزامنة (دعم تجمع الخيوط). لذلك ، يمكن إعادة كتابة طريقة بدء التشغيل () على النحو التالي:
تجمع خاص من executorservice pool = Executors.NewFixedThreadPool (10) ؛ inputStream input = url.openstream ()) {return ioutils.toString (input ، standardcharsets.utf_8) ؛}}) ؛}
على الرغم من أن هناك الكثير من المشكلات النحوية الشاقة ، إلا أن التفكير الأساسي بسيط: يتم تعبئة الحوسبة التي يجب تشغيلها لفترة طويلة إلى <String> القابلة للتعديل ، وتقديم () إلى تجمع الخيوط. المواضيع. بعد التقديم ، فإن تنفيذ Future <string> يشبه الارتباط بمهمتك ومجمع مؤشرات الترابط بطريقة ما. من الواضح أن مهمتك لن يتم تنفيذها على عكس ذلك. يمكن لمهمة البقاء في الوسط إلغاء المهمة التي تم تشغيلها منذ فترة طويلة ، ولكن هذا شيء أكثر تعقيدًا.
يمكنك أيضًا مقابلة المستقبل في الربيع و EJB. على سبيل المثال ، يمكنك إضافة شرح async إلى إطار الربيع:
asyncpublic future <string> startDownloading (url url النهائي) يلقي ioException {try (inputStream input = url.openstream ()) {return new Asyncres ult <>
لاحظ أننا ببساطة ننفذ المستقبل من خلال نتيجة التغليف إلى Asyncresult ، ولكن هذه الطريقة نفسها لن تتفاعل مع تجمع مؤشرات الترابط أو غير متزامن معالجته. سيمثل Spring لاحقًا جميع المكالمات إلى بدء التشغيل () وتنفيذها في مجموعة مؤشرات الترابط. في EJB ، يتم الانتهاء من نفس الميزة عن طريق إضافة asynchronousannotation.