اليوم سوف نتعلم كيفية أداء البرمجة غير المتزامنة في الربيع. نعلم جميعًا أن سلاسل الرسائل التي يتم الحصول request خادم الويب يتم الحصول عليها من تجمع مؤشرات الترابط ، والتي ليس من الصعب توضيحها ، لأنه عندما يكون عدد طلبات الويب كبيرة جدًا ، وكيفية إنشاء مؤشر ترابط معالجة عند ظهور طلب. نظرًا لأن النفقات العامة لإنشاء مؤشرات الترابط وتبديل مؤشرات الترابط يكون كبيرًا نسبيًا نسبيًا ، فإن خادم الويب سيواجه في النهاية. بالإضافة إلى ذلك ، يتم تنفيذ مؤشرات ترابط المعالجة التي تم إنشاؤها بواسطة خادم الويب بشكل متزامن من البداية إلى النهاية بشكل افتراضي. وهذا يعني ، إذا كانت معالجة مؤشر الترابط A مسؤولاً عن معالجة الطلب B ، فعندما لا return B ، لا يمكن معالجة مؤشر الترابط A الهروب لمعالجة الطلبات الأخرى ، مما سيحد بشكل كبير من إمكانية المعالجة المتزامنة لخادم الويب.
لذلك ، يحل تجمع الخيوط مشكلة إعادة تدوير مؤشرات الترابط ، لذا كيفية حل طلب المعالجة المتزامن؟ الجواب غير متزامن معالجة. ما هي المعالجة غير المتزامنة؟ تتيح المعالجة غير المتزامنة بشكل أساسي أن يكون طلب B أعلاه خمولًا قبل اكتمال معالجة الطلب أعلاه ، ويمكن تحرير الموضوع A لمواصلة معالجة الطلبات الأخرى. بعد ذلك ، يمكننا القيام بذلك ، وإعادة تشغيل مؤشر الترابط C ضمن مؤشر الترابط A لتنفيذ المهمة ، والسماح للعودة مباشرة إلى خادم الويب ، واستمر في قبول الطلبات الجديدة.
قبل البدء في التفسير أدناه ، سأقوم أولاً بتمييز مفهومين هنا:
1. ترابط العملية
مؤشر ترابط المعالجة ينتمي إلى خادم الويب ، وهو مسؤول عن معالجة طلبات المستخدم ، ويتم إدارته بواسطة مجموعة مؤشرات الترابط
2. الخيط غير المتزامن
مؤشرات الترابط غير المتزامنة هي مؤشرات ترابط معرفة المستخدم ويمكن إدارتها بواسطة تجمعات مؤشرات الترابط.
يوفر الربيع الدعم للمهام غير المتزامنة. يمكن تنفيذ المهام غير المتزامنة باستخدام فئة WebAsyncTask . في الوقت نفسه ، يمكننا أيضًا تعيين معالجة رد الاتصال المقابلة للمهام غير المتزامنة ، مثل كيفية التعامل مع المهمة ، وكيفية إلقاء استثناء. المهام غير المتزامنة عادة ما تكون عملية للغاية. على سبيل المثال ، نريد أن نترك عملية يمكن معالجتها لفترة طويلة للمعالجة غير المتزامن للمعالجة ، أو عندما يتم دفع طلب ، فإننا نمكّن المهمة غير المتزامنة من الاستعلام عن نتيجة دفع الطلب.
1. المهام غير المتزامنة العادية
للراحة التوضيحية ، يتم محاكاة تنفيذ المهام غير المتزامنة باستخدام Thread.sleep(long) . افترض الآن أن المستخدم يطلب الواجهة التالية:
http://localhost:7000/demo/getUserWithNoThing.json
يتم تعريف واجهة المهمة غير المتزامنة على النحو التالي:
/*** اختبار المهام غير المتزامنة دون أي استثناء*/@requestmapping (value = "getUserWithNothing.json" ، method = requestMethod.get) public webasynctask <string> getUserWithNothing () {// print processing name system.err.println ("اسم الموضوع الرئيسي هو" Thread.curteRead (). // هذا يحاكي فتح مهمة غير متزامنة ، مع مهلة من 10s WebasyNctask <string> task1 = جديد webasynctask <string> (10 * 1000L ، () -> {system.err.println 1000L) ؛ // يتم استدعاء الطريقة عند اكتمال تنفيذ المهمة Task1.OnCompletion (() -> {system.err.println ("المهمة 1 تنفيذ مكتملة!") ؛}) ؛ System.err.println ("Task1 تواصل التعامل مع الأشياء الأخرى!") ؛ إرجاع المهمة 1 ؛}تُطبع وحدة التحكم على النحو التالي:
اسم الموضوع الرئيسي هو HTTP-NIO-7000-EXEC-1
Task1 يستمر في التعامل مع أشياء أخرى!
اسم الموضوع الأول هو mvcasync1
تم الانتهاء من المهمة 1!
نتائج المتصفح كما يلي:
2. تجاوز الاستثناء المهمة غير المتزامنة
استدعاء الواجهة: http://localhost:7000/demo/getUserWithError.json
/*** اختبر المهمة غير المتزامنة حيث يحدث خطأ* regurn*/ @requestmapping (value = "getUserWitherRor.json" ، method = requestMethod.get) public webasynctask <string> getUserWitherror () مهمة غير متزامنة. webasynctask <string> task3 = جديد webasynctask <string> (10 * 1000L ، () -> {system.err.println ("اسم الخيط الثاني هو" + thread.currentThread (). getName () -> {system.err.println ("================================================================================= ================================================================================================================================= ================================================================================================================================= ==================================================================================================================================== "============================================================== =============================================================== =============================================================== =============================================================== =============================================================== =============================================================== =============================================================== ===============================================================إخراج وحدة التحكم على النحو التالي:
اسم الموضوع الرئيسي هو HTTP-NIO-7000-EXEC-1
تستمر Task3 في التعامل مع أشياء أخرى!
اسم الموضوع الثاني هو mvcasync1
2018-06-15 09: 40: 13.538 خطأ 9168 --- [NIO-7000-EXEC-2] OACCC [. [.java.lang.arithmeticexception: / by Zero
في com.example.demo.controller.getuserinfocontroller.lambda $ 5 (getUserInfoController.java:93) ~ [classes/: na]
في org.springframework.web.context.request.async.webasyncmanager.lambda $ startCallableProcessing $ 4 (webasyncmanager.java:317)
في java.util.concurrent.executors $ runnableadapter.call (Executors.java:511) ~ [Na: 1.8.0_161]
في java.util.concurrent.futureTask.run (futuretask.java:266) ~ [na: 1.8.0_161]
في java.lang.thread.run (thread.java:748) [NA: 1.8.0_161]2018-06-15 09: 40: 13.539 خطأ 9168 --- [NIO-7000-EXEC-2] OACCC [. [. الاستثناء المتداخل هو java.lang.arithmeticexception: / by Zero] مع السبب الجذري
java.lang.arithmeticexception: / by Zero
في com.example.demo.controller.getuserinfocontroller.lambda $ 5 (getUserInfoController.java:93) ~ [classes/: na]
في org.springframework.web.context.request.async.webasyncmanager.lambda $ startCallableProcessing $ 4 (webasyncmanager.java:317)
في java.util.concurrent.executors $ runnableadapter.call (Executors.java:511) ~ [Na: 1.8.0_161]
في java.util.concurrent.futureTask.run (futuretask.java:266) ~ [na: 1.8.0_161]
في java.lang.thread.run (thread.java:748) [NA: 1.8.0_161]======================================================================================
حدثت المهمة 3!
تم الانتهاء من المهمة 3!
بالطبع ، يمكنك أيضًا القيام ببعض الاستثناءات التي تعالج ما سبق لتجنب غير ودي رأي المستخدم. لمعالجة الاستثناءات ، يمكنك الاطلاع على مقال آخر في مقالتي حول استخدام نظام معالجة الأخطاء الموحدة في الربيع/الربيع
نتائج إخراج المتصفح:
3. المهلة غير المتزامنة
استدعاء الواجهة: http://localhost:7000/demo/getUserWithTimeOut.json
/*** اختبر المهمة غير المتزامنة التي توقيتها المهمة* regurn*/ @requestmapping (value = "getUserWithTimeout.json" ، method = requestMethod.get) public webasynctask <string> getUserWithTimeout () // يتم محاكاة هذا لبدء مهمة غير متزامنة ، مهلة 10S WebasyNctask <Tring> Task2 = New WebasyNctask <string> (10 * 1000L ، () -> {system.err.println ("اسم الموضوع الثاني هو" + thread.currentTheread (). getName () // Task Timeout تستدعي هذه الطريقة Task2.Ontimeout (() -> { System.err.println ("================================================================================== ==================================================================================================================================== ==================================================================================================================================== ==================================================================================================================================== "============================================================== =============================================================== =============================================================== =============================================================== =============================================================== =============================================================== =============================================================== ===============================================================نتائج تنفيذ وحدة التحكم:
اسم الموضوع الرئيسي هو HTTP-NIO-7000-EXEC-4
تواصل Task2 التعامل مع أشياء أخرى!
اسم الموضوع الثاني هو mvcasync2
==============================================================================================
تم الانتهاء من المهمة 2!
نتائج تنفيذ المتصفح:
4. تجمع الخيوط المهام غير المتزامنة
لا تتم إدارة المهام غير المتزامنة في الحالات الثلاث المذكورة أعلاه بواسطة آلية تجمع الخيوط افتراضيًا. وهذا يعني ، إذا جاء الطلب ، على الرغم من إصدار مؤشر ترابط المعالجة ، سيظل النظام يخلق مؤشر ترابط مهمة غير متزامن لكل طلب ، وهو مؤشر ترابط المهمة غير المتزامن بدءًا من MvcAsync كما رأينا أعلاه. وهذا هو ، هذا لن ينجح ، والنفقات العامة عالية بشكل خاص! لذلك ، يمكننا استخدام مجموعة مؤشرات الترابط للإدارة وتمرير مثيل كائن ThreadPoolTaskExecutor مباشرة في مُنشئ فئة WebAsyncTask .
دعونا أولاً نلقي نظرة على ما يحدث عند إجراء الطلبات المتزامنة في الحالة الأولى أعلاه (هنا نقوم بمحاكاة المكالمات المتزامنة إلى http://localhost:7000/demo/getUserWithNoThing.json ):
إخراج وحدة التحكم على النحو التالي:
اسم الموضوع الأول هو mvcasync57
اسم الموضوع الأول هو mvcasync58
اسم الموضوع الأول هو mvcasync59
اسم الموضوع الأول هو mvcasync60
اسم الموضوع الأول هو mvcasync61
اسم الموضوع الأول هو mvcasync62
اسم الموضوع الأول هو mvcasync63
اسم الموضوع الأول هو mvcasync64
اسم الموضوع الأول هو mvcasync65
اسم الموضوع الأول هو mvcasync66
اسم الموضوع الأول هو mvcasync67
اسم الموضوع الأول هو mvcasync68
اسم الموضوع الأول هو mvcasync69
اسم الموضوع الأول هو mvcasync70
اسم الموضوع الأول هو mvcasync71
اسم الموضوع الأول هو mvcasync72
اسم الموضوع الأول هو mvcasync73
اسم الموضوع الأول هو mvcasync74
اسم الموضوع الأول هو mvcasync76
اسم الموضوع الأول هو mvcasync75
اسم الموضوع الأول هو mvcasync77
اسم الموضوع الأول هو mvcasync78
اسم الموضوع الأول هو mvcasync79
اسم الموضوع الأول هو mvcasync80
نظرًا لعدم إضافة تجمع مؤشرات الترابط ، سيفتح 100 طلب 100 سلسلة من مؤشر ترابط المهام غير المتزامن ، وهو مكلف بشكل خاص ولا ينصح به.
فيما يلي تنفيذ تجمع الخيوط:
واجهة الاتصال: http://localhost:7000/demo/getUserWithExecutor.json
/*** Test Thread Pool* @return*/ @requestmapping (value = "getUserWithExecutor.json" ، method = requestMethod.get) public webasynctask <string> getUserWithExecutor () {system.err.println ("اسم الموضوع الرئيسي" + thread.currentThread (). getName () ؛ // يتم محاكاة هذا لبدء مهمة غير متزامنة ، ويتم تمرير تجمع مؤشرات الترابط هنا. WebAsyNctask <Tring> task1 = new WebAsyNctask <Tring> (10 * 1000L ، Executor ، () -> {system.err.println ("اسم الموضوع الأول هو" + thread.currentThread (). // استدعاء هذه الطريقة عند اكتمال تنفيذ المهمة Task1.OnCompletion (() -> {system.err.println ("Task 4 تنفيذ مكتمل!") ؛}) ؛ System.err.println ("Task4 تواصل التعامل مع الأشياء الأخرى!") ؛ إرجاع المهمة 1 ؛}يتم تعريف تجمع الخيوط على النحو التالي:
ConfigurationPublic Class MyExecutor {bean public static threadpooltaskexecutor getExecutor () {threadpooltaskexecutor taskexecutor = new threadpooltaskexecutor () ؛ taskexecutor.setCorepoolsize (30) ؛ taskexecutor.setMaxPoolsize (30) ؛ taskexecutor.setqueuecapacity (50) ؛ Taskexecutor.setThreadnamePrefix ("Huang") ؛ // اسم مؤشر ترابط المهمة غير المتزامن هو Huang Prefix Return Taskexecutor ؛ }}يمكن استخدام الاختبارات المتزامنة أعلاه للحصول على النتائج التالية:
عنوان رمز نموذج هذه المقالة: https://github.com/smallercoder/webasynctask
يمكن أن يؤدي استخدام تجمعات مؤشرات الترابط إلى حفظ موارد الخادم وتحسين إمكانيات معالجة الخادم. تذكر استخدامها بشكل متكرر! شكرا للقراءة! إذا كنت تعتقد أنه سيكون مفيدًا لك ، فيرجى البدء!
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.