تحلل هذه المقالة أربعة مجموعة من تجمع الخيوط Java للرجوع إليها. المحتوى المحدد كما يلي
1. عيوب الخيط الجديد
هل ما زلت تنفذ فقط موضوعًا جديدًا على النحو التالي عند تنفيذ مهمة غير متزامنة؟
مؤشر ترابط جديد (جديد RunNable () {Override public void run () {// todo method method method old}}). start () ؛بعد ذلك ، سيكون لديك الكثير من الرافضة ، وعيوب الخيط الجديد هي كما يلي:
أ. أداء الخيط الجديد ضعيف في كل مرة.
ب. تفتقر المواضيع إلى الإدارة الموحدة ، والتي قد تنشئ مؤشرات ترابط جديدة دون قيود ، وتتنافس مع بعضها البعض ، وقد تشغل الكثير من موارد النظام للتسبب في حوادث أو OOMs.
ج. عدم وجود المزيد من الوظائف ، مثل التنفيذ المحدد ، التنفيذ الدوري ، انقطاع مؤشر الترابط.
بالمقارنة مع الخيط الجديد ، فإن مزايا تجمعات الخيوط الأربعة التي توفرها Java هي:
أ. إعادة استخدام المواضيع الحالية لتقليل النفقات العامة لإنشاء الكائن والانقراض ، والأداء بشكل جيد.
ب. يمكن أن يتحكم بشكل فعال في الحد الأقصى لعدد الخيوط المتزامنة ، وتحسين معدل استخدام موارد النظام ، وتجنب المنافسة المفرطة للموارد وتجنب الانسداد.
ج. يوفر وظائف مثل التنفيذ المحدد ، والتنفيذ المنتظم ، والخيط المفرد ، والتحكم المتزامن في الأرقام ، إلخ.
2. تجمع خيوط جافا
توفر Java أربعة أنواع من تجمعات الخيوط من خلال المنفذين ، وهي:
NewCachedThreadPool ينشئ تجمع الخيوط القابلة للتخطيط. إذا تجاوز طول تجمع الخيط احتياجات المعالجة ، فيمكنه إعادة تدوير مؤشرات الترابط الخاملة بمرونة. إذا لم يكن هناك إعادة تدوير ، قم بإنشاء موضوع جديد.
تقوم NewFixedThreadPool بإنشاء تجمع مؤشر ترابط ثابت طوله يمكنه التحكم في الحد الأقصى لعدد مؤشرات الترابط ، وسوف تنتظر مؤشرات الترابط الزائدة في قائمة الانتظار.
تنشئ NewsCheduledThreadPool تجمع مؤشرات ترابط ثابت الطول يدعم تنفيذ المهمة المحددة والدورية.
تقوم NewsingLethReadExecutor بإنشاء تجمع مؤشرات ترابط واحد ، والذي سيستخدم فقط مؤشر ترابط عامل فريد لتنفيذ المهام ، مما يضمن تنفيذ جميع المهام بالترتيب المحدد (FIFO ، LIFO ، الأولوية).
(1) NewCachedThreadPool:
قم بإنشاء تجمع خيوط قابل للتخطيط. إذا تجاوز طول تجمع الخيوط احتياجات المعالجة ، فيمكنك إعادة تدوير مؤشرات الترابط الخاملة بمرونة. إذا لم يكن هناك إعادة تدوير ، قم بإنشاء موضوع جديد. رمز العينة كما يلي:
ExecutorService CacheDthReadPool = Executors.NewCacheDthReadPool () ؛ لـ (int i = 0 ؛ i <10 ؛ i ++) {final int index = i ؛ حاول {thread.sleep (index * 1000) ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ } cacheDthReadPool.execute (new RunNable () {OverRidepublic void run () {system.out.println (index) ؛}}) ؛}تجمع الخيوط لا حصر له. عند تنفيذ المهمة الثانية ، تم الانتهاء من المهمة الأولى ، وسيتم إعادة استخدام الخيط الذي ينفذ المهمة الأولى دون إنشاء سلسلة رسائل جديدة في كل مرة.
(2) NewfixedThreadPool:
قم بإنشاء تجمع مؤشر ترابط ثابت طوله يمكنه التحكم في الحد الأقصى لعدد مؤشرات الترابط ، وسوف تنتظر مؤشرات الترابط الزائدة في قائمة الانتظار. رمز العينة كما يلي:
ExecutorService FixedThreadPool = Executors.NewFixedThreadPool (3) ؛ لـ (int i = 0 ؛ i <10 ؛ i ++) {final int index = i ؛ flexthreadpool.execute (new runnable () {OverRidepublic void run () {try {system.out.println (index) ؛ thread.sleep (2000) ؛نظرًا لأن حجم تجمع الخيوط هو 3 ، النوم بعد ثانيتين من فهرس كل مهمة ، لذلك تتم طباعة 3 أرقام كل ثانيتين.
يتم تعيين حجم تجمع مؤشرات الترابط ذات الطول الثابت وفقًا لموارد النظام. مثل Runtime.getRuntime (). AvailableProcessors (). يرجى الرجوع إلى preloaddatacache.
(3) NewscheduledThreadPool:
قم بإنشاء تجمع مؤشر ترابط ثابت ذو طول يدعم تنفيذ المهمة الموقوت والدوري. رمز عينة للتأخر في التنفيذ هو كما يلي:
ScripedExecutorService SchedultHreadPool = Executors.NewScheduledThreadPool (5) ؛ SecrledThreadPool.Schedule (new RunNable () {Overridepublic void run () {system.out.println ("Delay 3 Seconds") ؛}} ، 3 ، timunit.seconds) ؛يشير إلى تأخير تنفيذ لمدة 3 ثوان.
يتم تنفيذ رمز العينة بانتظام على النحو التالي:
SchedulThReadPool.ScheduleAtfixedRate (new RunNable () {Overridepublic void Run () {system.out.println ("تأخير 1 ثانية ، و excute كل 3 ثوان") ؛} ، 1 ، 3 ، timeunit.seconds) ؛وهذا يعني أن التأخير يتم تنفيذ كل 3 ثوانٍ بعد ثانية واحدة.
SchedeDexecutorService أكثر أمانًا وأقوى من المؤقت
(4) Newsinglethreadexecutor:
قم بإنشاء تجمع مؤشرات ترابط واحد ، والذي سيستخدم فقط مؤشر ترابط عامل فريد لتنفيذ المهام ، مما يضمن تنفيذ جميع المهام بالترتيب المحدد (FIFO ، LIFO ، الأولوية). رمز العينة كما يلي:
ExecutorService SingleThreAdexecutor = evelopors.newsingleTheReadExecutor () ؛ for (int i = 0 ؛ i <10 ؛ i ++) {final int index = i ؛ singlethreadexutor.execute (new Runnable () {overridepublic run () {try {system.print.println) (InterruptedException e) {// todo catch e.printstacktrace () ؛يتم إخراج النتائج بالتسلسل ، وهو ما يعادل تنفيذ كل مهمة بالتسلسل.
معظم برامج واجهة المستخدم الرسومية الحالية هي واحدة. يمكن استخدام مؤشرات الترابط المفردة في Android لعمليات قاعدة البيانات ، وعمليات الملفات ، وتركيب الدُفعات للتطبيقات ، وحذف الدُفعات للتطبيقات ، وما إلى ذلك ، والتي ليست مناسبة للتزامن ولكن قد تمنع IO وتؤثر على استجابة مؤشرات ترابط واجهة المستخدم.
وظيفة تجمع الخيوط:
تتمثل وظيفة تجمع مؤشرات الترابط في الحد من عدد مؤشرات الترابط التي تم تنفيذها في النظام.
اعتمادًا على بيئة النظام ، يمكن تعيين عدد مؤشرات الترابط تلقائيًا أو يدويًا لتحقيق أفضل تأثير للتشغيل ؛ يتم إهدار موارد النظام الأقل ، ومزيد من احتقان النظام ليس مرتفعًا. استخدم تجمع مؤشرات الترابط للتحكم في عدد مؤشرات الترابط ، وينتظر مؤشرات الترابط الأخرى في الخط. بعد تنفيذ المهمة ، يتم أخذ المهمة الأولى من قائمة الانتظار لبدء التنفيذ. إذا لم تكن هناك عملية انتظار في قائمة الانتظار ، فإن مورد تجمع الخيوط هذا ينتظر. عندما تحتاج مهمة جديدة إلى تشغيل ، إذا كانت هناك مؤشرات ترابط عامل انتظار في مجموعة مؤشرات الترابط ، فيمكنها البدء في التشغيل ؛ خلاف ذلك ، سوف يدخل قائمة انتظار الانتظار.
لماذا تستخدم تجمع المواضيع:
1. يقلل من عدد المرات التي يتم إنشاء مؤشرات الترابط وتدميرها ، ويمكن إعادة استخدام كل موضوع عامل ويمكنه أداء مهام متعددة.
2. يمكن ضبط عدد مؤشرات ترابط العمال في تجمع مؤشرات الترابط وفقًا لقدرة النظام على منع الخادم من امتصاصه بسبب استهلاك الذاكرة المفرط (يتطلب كل مؤشر ترابط حوالي 1 ميجابايت من الذاكرة. كلما تم فتح مؤشرات الترابط ، كلما زاد استهلاك الذاكرة ، وأخيراً سيكون الحادث.
الواجهة ذات المستوى الأعلى لمجموعة مؤشرات الترابط في Java هي المنفذ ، ولكن بالمعنى الدقيق للكلمة ، فإن Executor ليس مجموعة مؤشرات ترابط ، ولكن مجرد أداة لتنفيذ مؤشرات الترابط. واجهة تجمع الخيوط الحقيقية هي ExecutorService.
عدة فئات أكثر أهمية:
ExecutorService: واجهة تجمع مؤشرات الترابط الحقيقية.
SchedeDexecutorService: يمكن أن يكون مشابهًا لمؤقت/timertask ، مما يتطلب المشكلات التي تتطلب مهام متكررة.
ThreadPoolexecutor: التنفيذ الافتراضي لـ ExecutorService.
SecrettHreadPoolexecutor: تنفيذ فئة لواجهة ScripedExecutorService التي ترث ThreadPoolexecutor ، وهو تطبيق فئة دورية لجدولة المهام.
من المعقد للغاية تكوين تجمع مؤشرات الترابط ، خاصةً عندما يكون مبدأ تجمع الخيوط غير واضح للغاية. من المحتمل جدًا أن تجمع مؤشرات الترابط الذي تم تكوينه ليس أفضل. لذلك ، يتم توفير بعض المصانع الثابتة في فئة المنفذين لإنشاء بعض تجمعات الخيوط شائعة الاستخدام.
1.newsinglethreadexecutor
إنشاء تجمع مؤشر ترابط واحد. يحتوي تجمع الخيوط هذا على مؤشر ترابط واحد فقط يعمل ، وهو ما يعادل مؤشر ترابط واحد يقوم بجميع المهام في المسلسل. إذا انتهى هذا الخيط الفريد بسبب الاستثناء ، فسيكون هناك مؤشر ترابط جديد لاستبداله. يضمن تجمع مؤشرات الترابط هذا تنفيذ ترتيب تنفيذ جميع المهام بترتيب تقديم المهمة.
2.NewFixedThreadPool
قم بإنشاء تجمع خيوط ثابت الحجم. في كل مرة يتم فيها تقديم مهمة ، يتم إنشاء مؤشر ترابط حتى يصل مؤشر الترابط إلى الحد الأقصى لحجم تجمع الخيوط. يبقى حجم تجمع الخيوط كما هو بمجرد وصوله إلى أقصى قيمته. إذا انتهى مؤشر ترابط بسبب استثناء التنفيذ ، فسيضيف تجمع مؤشرات الترابط مؤشر ترابط جديد.
3.newcachedthreadpool
قم بإنشاء تجمع خيوط قابل للتخطيط. إذا تجاوز حجم تجمع الخيط الخيط المطلوب لمعالجة المهمة ،
ثم سيتم إعادة تدوير بعض مؤشرات الترابط الخمول (لا تنفيذ المهمة في 60 ثانية). عندما يزداد عدد المهام ، يمكن لتجمع مؤشرات الترابط هذا إضافة مؤشرات ترابط جديدة بذكاء للتعامل مع المهمة. لا يحد تجمع مؤشرات الترابط هذا من حجم تجمع مؤشرات الترابط ، والذي يعتمد كليا على الحد الأقصى لحجم مؤشر الترابط الذي يمكن أن ينشئه نظام التشغيل (أو JVM).
4. newscheduledThreadPool
إنشاء مجموعة مؤشر ترابط من حجم غير محدود. يدعم تجمع الخيوط هذا الحاجة إلى أداء المهام بشكل دوري وفوري.
رمز مثال
1. تجمع الخيوط ذات الحجم الثابت ، newfixedThreadPool:
package app.executors ؛ استيراد java.util.concurrent.executors ؛ استيراد java.util.concurrent.executorservice ؛ / ** * Java Thread: Thread Pool * * Author Xiho */ test class public {public static void main (string [] args) {// قم بإنشاء تجمع مؤشر ترابط مع عدد ثابت من المواضيع القابلة لإعادة الاستخدام ExecutorService Pool = Executors.NewFixedThreadPool (2) ؛ // إنشاء مؤشر ترابط THELL T1 = جديد myThread () ؛ الموضوع T2 = جديد myThread () ؛ الموضوع T3 = جديد myThread () ؛ الموضوع T4 = جديد myThread () ؛ الموضوع T5 = جديد myThread () ؛ // ضع الخيط في تجمع تجمع التنفيذ. Execute (T1) ؛ pool.execute (t2) ؛ pool.execute (t3) ؛ pool.execute (t4) ؛ pool.execute (t5) ؛ // أغلق بركة المسبح. shutdown () ؛ }} class myThread يمتد Thread {Override public void run () {system.out.println (thread.currentThRead (). getName () + "تنفيذ ...") ؛ }}نتيجة الإخراج:
Pool-1-Thread-1 ينفذ. . . Pool-1-Thread-3 يتم تنفيذها. . . Pool-1-Thread-4 ينفذ. . . Pool-1-Thread-2 ينفذ. . . يتم تنفيذ pool-1-thread-5. . .
قم بتغيير المعلمات في تجمع ExecutorService = Executors.NewFixedThreadPool (5): ExecutorService Pool = Executors.NewFixedThreadPool (2) ، ونتيجة الإخراج هي:
Pool-1-Thread-1 ينفذ. . . Pool-1-Thread-1 ينفذ. . . Pool-1-Thread-2 ينفذ. . . Pool-1-Thread-1 ينفذ. . . Pool-1-Thread-2 ينفذ. . .
من النتائج المذكورة أعلاه ، يمكننا أن نرى أن معلمة NewFixedThreadPool تحدد الحد الأقصى لعدد الخيوط التي يمكن تشغيلها. بعد إضافة أكثر من هذا العدد من المواضيع ، لن يتم تشغيلها. ثانياً ، توجد مؤشرات الترابط المضافة إلى تجمع مؤشرات الترابط في الحالة المدارة ، ولا تتأثر تشغيل مؤشر الترابط بأمر الانضمام.
2. تجمع سلسلة المهام الفردية ، NewsingleTheReadExecutor:
فقط قم بتغيير مجموعة ExecutorService = Executors.NewFixedThreadPool (2) في الكود أعلاه إلى ExecutorService Pool = Executors.NewsingleThreadExecutor () ؛
نتيجة الإخراج:
Pool-1-Thread-1 ينفذ. . . Pool-1-Thread-1 ينفذ. . . Pool-1-Thread-1 ينفذ. . . Pool-1-Thread-1 ينفذ. . . Pool-1-Thread-1 ينفذ. . .
يمكن ملاحظة أنه في كل مرة تتصل فيها طريقة التنفيذ ، يتم استدعاء طريقة تشغيل Thread-1 فعليًا في النهاية.
3. تجمع مؤشر ترابط الحجم المتغير ، NewCachedThreadPool:
على غرار ما سبق ، فقط قم بتغيير طريقة إنشاء التجمع: ExecutorService Pool = Executors.NewCachedThreadPool () ؛
نتيجة الإخراج:
Pool-1-Thread-1 ينفذ. . . Pool-1-Thread-2 ينفذ. . . Pool-1-Thread-4 ينفذ. . . Pool-1-Thread-3 يتم تنفيذها. . . يتم تنفيذ pool-1-thread-5. . .
تتميز هذه الطريقة بحقيقة أنه يمكن إنشاء تجمعات مؤشرات ترابط جديدة حسب الحاجة ، ولكن سيتم إعادة استخدامها عند توفر مؤشرات الترابط التي تم إنشاؤها مسبقًا.
4. تجمع اتصال التأخير ، newscheduledthreadpool:
اختبار الفئة العامة TestSchedThedThreadPoolexecutor {public static void main (string [] args) {SecrettHreadPoolExecutor exec = new SecretThreadPoolexecutor (1) ؛ exec.ScheDuleAtfixedRate (new RunNable () {// استثناء يتم تشغيله كل مرة في وقت واحد @override publicvoid run () {// رمي new RunTimeException () ؛ System.out.println ("============================================================================= ============================================================================================================================ ============================================================================================================================ ============================================================================================================================ timeunit.milliseconds) ؛نتيجة الإخراج:
===================================================================== 8390643851383839264387931984
ما سبق هو كل شيء عن هذا المقال ، آمل أن يكون مفيدًا لتعلم الجميع.