2. مقدمة
تحل تقنية Multithreading بشكل أساسي مشكلة تنفيذ مؤشرات الترابط المتعددة في وحدة المعالج. يمكن أن يقلل بشكل كبير من وقت الخمول لوحدة المعالج وزيادة قدرة الإنتاجية لوحدة المعالج. ومع ذلك ، فإن النفقات العامة لإنشاء الخيط المتكرر كبير جدا. لذا ، كيفية تقليل هذا الجزء من النفقات العامة ، تحتاج إلى التفكير في استخدام تجمع مؤشرات الترابط. تجمع مؤشرات الترابط هو حاوية مؤشر ترابط ، والتي تنفذ فقط عدد مصنّف من مؤشرات الترابط في وقت واحد. يتم استخدام تجمع مؤشرات الترابط لإدارة هذا العدد المصنف من مؤشرات الترابط.
3. مخطط هيكل الفصل الذي يتضمن تجمع الخيوط
من بينها ، الفئة الرئيسية بالنسبة لنا لاستخدامها هي فئة ThreadPoolexecutor.
4. كيفية إنشاء تجمع الخيوط
لدينا عمومًا الطرق التالية لإنشاء تجمعات مؤشرات ترابط:
1. استخدم فئة مصنع المنفذين
يوفر المنفذون الأساليب التالية بشكل أساسي لإنشاء تجمعات مؤشرات الترابط:
دعونا نلقي نظرة على مثال الاستخدام أدناه:
1) NewfixedThreadPool (تجمع الخيوط الثابتة)
الفئة العامة الثابتة {public static void main (string [] args) {ExecutorService Pool = Executors.NewFixedThreadPool (5) ؛ // قم بإنشاء تجمع مؤشر ترابط بحجم ثابت قدره 5 لـ (int i = 0 ؛ i <10 ؛ i ++) {pool.submit (new Mythread ()) ؛ } pool.shutdown () ؛ }} الفئة العامة myThread يمتد Thread {Override public void run () {system.out.println (thread.currentThRead (). getName () + "التنفيذ ...") ؛ }}نتائج الاختبار كما يلي:
Pool-1-Thread-1 ينفذ. . .
Pool-1-Thread-2 ينفذ. . .
Pool-1-Thread-3 يتم تنفيذها. . .
Pool-1-Thread-2 ينفذ. . .
Pool-1-Thread-3 يتم تنفيذها. . .
Pool-1-Thread-2 ينفذ. . .
Pool-1-Thread-2 ينفذ. . .
Pool-1-Thread-3 يتم تنفيذها. . .
يتم تنفيذ pool-1-thread-5. . .
Pool-1-Thread-4 ينفذ. . .
تجمع مؤشرات الترابط ذات الحجم الثابت: قم بإنشاء مؤشر ترابط في كل مرة يتم فيها تقديم مهمة ، حتى يصل مؤشر الترابط إلى الحد الأقصى لحجم تجمع الخيوط. سيبقى حجم تجمع الخيوط دون تغيير بمجرد وصوله إلى أقصى قيمته. إذا انتهى مؤشر ترابط بسبب استثناء التنفيذ ، فسيضيف تجمع مؤشرات الترابط مؤشر ترابط جديد.
2) NEWSINGLETHREADEXECUTOR (تجمع موضوع واحد)
الطبقة العامة SingleThreadPool {public static void main (string [] args) {evelicororservice pool = evelivors.newsinglethreadexecutor () ؛ // إنشاء مجموعة مؤشر ترابط واحدة لـ (int i = 0 ؛ i <100 ؛ i ++) {pool.submit (mythread () new ()) ؛ } pool.shutdown () ؛ }}نتائج الاختبار كما يلي:
Pool-1-Thread-1 ينفذ. . .
Pool-1-Thread-1 ينفذ. . .
Pool-1-Thread-1 ينفذ. . .
Pool-1-Thread-1 ينفذ. . .
Pool-1-Thread-1 ينفذ. . .
Pool-1-Thread-1 ينفذ. . .
Pool-1-Thread-1 ينفذ. . .
Pool-1-Thread-1 ينفذ. . .
Pool-1-Thread-1 ينفذ. . .
Pool-1-Thread-1 ينفذ. . .
تجمع مؤشرات الترابط المفرد: يحتوي تجمع الخيوط هذا على مؤشر ترابط واحد فقط ، مما يعني أن التنفيذ التسلسلي المتسلسل واحد لجميع المهام. إذا انتهى هذا الخيط الفريد بسبب الاستثناء ، فسيكون هناك مؤشر ترابط جديد لاستبداله. يضمن تجمع مؤشرات الترابط هذا تنفيذ ترتيب تنفيذ جميع المهام بترتيب تقديم المهمة.
3) الأخبار
الفئة العامة ScreadThreadPool {public static void main (string [] args) {ScripedExecutorService Pool = Executors.NewScheduledThreadPool (6) ؛ لـ (int i = 0 ؛ i <10000 ؛ i ++) {pool.submit (new MyThread ()) ؛ } pool.schedule (new MyThread () ، 1000 ، timeUnit.milliseconds) ؛ pool.schedule (new MyThread () ، 1000 ، timeUnit.MillisEconds) ؛ pool.shutdown () ؛ }}نتائج الاختبار كما يلي:
Pool-1-Thread-1 ينفذ. . .
Pool-1-Thread-6 يتم تنفيذها. . .
يتم تنفيذ pool-1-thread-5. . .
Pool-1-Thread-4 ينفذ. . .
Pool-1-Thread-2 ينفذ. . .
Pool-1-Thread-3 يتم تنفيذها. . .
Pool-1-Thread-4 ينفذ. . .
يتم تنفيذ pool-1-thread-5. . .
Pool-1-Thread-6 يتم تنفيذها. . .
Pool-1-Thread-1 ينفذ. . .
....................................................................................................................................................................................................................................... .......................................................................................................................................................................................................................................
Pool-1-Thread-4 ينفذ. . .
Pool-1-Thread-1 ينفذ. . .
آخر موضوعين من نتيجة الاختبار تبدأ فقط في التنفيذ بعد تأخير 1s. يدعم تجمع الخيوط هذا متطلبات التوقيت والتنفيذ الدوري للمهام
4) NewCachedThreadPool (تجمع الخيوط القابل للتخطيط)
الفئة العامة CacheDthReadPool {public static void main (string [] args) {executorService pool = evelivors.newcachedthreadpool () ؛ لـ (int i = 0 ؛ i <100 ؛ i ++) {pool.submit (new MyThread ()) ؛ } pool.shutdown () ؛ }}نتائج الاختبار كما يلي:
يتم تنفيذ pool-1-thread-5. . .
Pool-1-Thread-7 ينفذ. . .
يتم تنفيذ pool-1-thread-5. . .
Pool-1-Thread-16 في التنفيذ. . .
Pool-1-Thread-17 ينفذ. . .
Pool-1-Thread-16 في التنفيذ. . .
يتم تنفيذ pool-1-thread-5. . .
Pool-1-Thread-7 ينفذ. . .
Pool-1-Thread-16 في التنفيذ. . .
Pool-1-Thread-18 ينفذ. . .
Pool-1-Thread-10 ينفذ. . .
تجمع مؤشرات الترابط القابل للتخزين المؤقت: إذا تجاوز حجم تجمع مؤشرات الترابط الخيط المطلوب لمعالجة المهمة ، فسيتم إعادة تدوير بعض مؤشرات الترابط الخاملة (بدون تنفيذ المهمة في 60 ثانية). عندما يزداد عدد المهام ، يمكن لتجمع مؤشرات الترابط هذا إضافة مؤشرات ترابط جديدة بذكاء للتعامل مع المهمة. لا يحد تجمع مؤشرات الترابط هذا من حجم تجمع مؤشرات الترابط ، والذي يعتمد كليا على الحد الأقصى لحجم مؤشر الترابط الذي يمكن أن ينشئه نظام التشغيل (أو JVM).
يشير المسؤول إلى أن المبرمجين يستخدمون أساليب مصنع المنفذين الأكثر ملاءمة. newcachedthreadpool () (تجمع مؤشرات ترابط غير محدود ، والذي يمكنه إجراء إعادة تدوير مؤشرات الترابط التلقائي) ، المنفذون. يتم تعريف تجمعات مؤشرات الترابط هذه مسبقًا بشكل افتراضي لمعظم سيناريوهات الاستخدام.
2. ورث فئة ThreadPoolexecutor ونسخ طريقة مُنشئ الفئة الأصل.
قبل تقديم هذه الطريقة ، دعنا نحلل الرموز الأساسية القليلة السابقة لإنشاء تجمعات مؤشرات الترابط؟
منفذ الفئة العامة {public static eventorservice newfixedthreadpool (int nthreads) {return new threadpoolexecutor (nThReads ، nThReads ، 0L ، timeUnit.milliseconds ، new LinkedBlockingqueue <Runnable> ()) ؛ } static static eventorservice newsinglethreadexecutor () {return new finizabledlegatedexecutorservice (new threadpoolexecutor (1 ، 1 ، 0L ، timeUnit.milliseconds ، new LinkedBlockingqueue <Runnable> ())) ؛ }}من الكود الأساسي لفئة مصنع المنفذين ، يمكننا أن نرى أن الأساليب التي توفرها فئة المصنع لإنشاء تجمعات مؤشرات الترابط يتم تنفيذها فعليًا عن طريق إنشاء ThreadPoolexecutor. رمز طريقة مُنشئ ThreadPoolexecutor هو كما يلي:
public threadpoolexecutor (int corePoolsize ، int maximumpoolsize ، keepalivetime الطويل ، الوحدة الزمنية ، blockingqueue <runnable> workqueue ، threadfactory threadfactory ، desideedExecutionHandler معالج) غير unalfalArgumentException () ؛ if (workqueue == null || threadfactory == null || handler == null) رمي nullpointerexception () ؛ this.corepoolsize = corePoolSize ؛ this.maximumpoolsize = maximumpoolsize ؛ this.workqueue = workqueue ؛ this.keepalivetime = unit.tonanos (keepalivetime) ؛ this.threadfactory = threadfactory ؛ this.handler = معالج ؛ }
ثم ، دعنا نتحدث عن طريقة مُنشئ Threadpoolexecutor. في طريقة البناء هذه ، هناك بشكل أساسي المعلمات التالية:
CorePoolsize-عدد الخيوط المحفوظة في حمام السباحة ، بما في ذلك الخيوط الحرة.
MaximumpoolSize - الحد الأقصى لعدد الخيوط المسموح بها في المجمع.
KeepAlivetime-عندما يكون عدد المواضيع أكبر من CorePoolsize ، هذا هو أطول وقت لانتظار مؤشر الترابط الخمول لمهمة جديدة.
الوحدة- وحدة وقت معلمة Keepalivetime.
WorkQueue-قائمة الانتظار المستخدمة للحفاظ على المهام قبل التنفيذ. تحافظ هذه قائمة الانتظار فقط على المهام القابلة للتشغيل المقدمة من طريقة التنفيذ.
ThreadFactory-المصنع الذي يستخدمه المنفذون لإنشاء مؤشرات ترابط جديدة.
المعالج-المعالج المستخدم عندما يتم حظر التنفيذ بسبب نطاق مؤشر الترابط وقدرة قائمة الانتظار.
بعد ذلك ، دعنا نتحدث عن العلاقة بين هذه المعلمات. عند إنشاء تجمع مؤشرات الترابط للتو ، لا توجد مؤشرات ترابط في تجمع مؤشرات الترابط (لاحظ أنه لا يتم إنشاء عدد معين من مؤشرات الترابط بمجرد إنشاء تجمع مؤشرات الترابط). عندما يتم استدعاء طريقة Execute () لإضافة مهمة ، فإن مجموعة مؤشرات الترابط ستصدر الحكم التالي:
1) إذا كان عدد المواضيع التي تعمل حاليًا أقل من CorePoolsize ، فقم بإنشاء مؤشر ترابط جديد على الفور لأداء هذه المهمة.
2) إذا كان عدد المواضيع التي تعمل حاليًا أكبر من أو تساوي CorePoolsize ، فسيتم وضع هذه المهمة في قائمة الانتظار.
3) إذا كانت قائمة انتظار تجمع الخيوط ممتلئة ، ولكن عدد مؤشرات الترابط الجارية أقل من MaximumpoolSize ، فسيتم إنشاء مؤشر ترابط جديد لأداء هذه المهمة.
4) إذا كانت قائمة الانتظار ممتلئة وكان عدد مؤشرات الترابط التي تعمل حاليًا أكبر من أو يساوي Maximumpoolsize ، فسيتعامل تجمع مؤشرات الترابط مع المهمة الحالية بناءً على سياسة الرفض.
5) عند تنفيذ المهمة ، سيأخذ مؤشر الترابط المهمة التالية من قائمة الانتظار لتنفيذها. إذا لم تكن هناك مهمة يتم تنفيذها في قائمة الانتظار ، فسيكون الخيط خمولًا. في حالة تجاوز وقت البقاء على قيد الحياة من keepalivetime ، سيتم إعادة تدوير الخيط بواسطة مجموعة الخيوط (ملاحظة: إعادة تدوير المواضيع مشروطة. إذا كان عدد الخيوط التي تعمل حاليًا أكبر من CorePoolsize ، فسيتم تدمير الخيط. لماذا لا يتم إعادة تدوير الخيط بمجرد أن يكون خاملاً ، ولكنه يحتاج إلى الانتظار حتى يتجاوز الاحتفاظ به قبل إعادة تدوير الخيط؟ السبب بسيط للغاية: لأن إنشاء وتدمير المواضيع يستهلك الكثير ، ولا يمكن إنشاؤه وتدميره بشكل متكرر. بعد تجاوز keepalivetime ، وجد أن هذا الخيط غير مستخدم بالفعل ، وسيتم تدميره. في هذه الحالة ، تمثل الوحدة الوحدة الزمنية لـ Keepalivetime ، وتعريف الوحدة كما يلي:
التعداد العام timunit {nanoSeconds {// keepaliveTime في nanoSeconds} ، microseconds {// keepaliveTime في microseconds} ، milliseconds {// keepalivetime in millisonds} ، seconds {// keepalivet in seconds}} keepalivetime في ساعات} ، أيام {// keepalivetime في الأيام} ؛ دعنا نحلل رمز المصدر أدناه. بالنسبة للحالات المذكورة أعلاه ، فإن رموز المصدر المعنية بشكل أساسي هي ما يلي:
addifunderCorePoolsize الخاص المنطقي (runnable firstTask) {thread t = null ؛ النهائي reentrantlock mainlock = this.mainlock ؛ mainlock.lock () ؛ جرب {if (poolsize <corePoolSize && runstate == running) t = addThread (firstTask) ؛ } أخيرًا {mainlock.unlock () ؛ } if (t == null) return false ؛ T.Start () ؛ العودة صحيح. } في الواقع ، هذا الرمز بسيط للغاية. يصف بشكل أساسي أنه إذا كان تجمع مؤشرات الترابط الحالي أصغر من CorePoolsize ، يتم إنشاء مؤشر ترابط جديد للتعامل مع المهمة.
خاص boolean addifunderMaxImumpoolSize (runnable firstTask) {thread t = null ؛ النهائي reentrantlock mainlock = this.mainlock ؛ mainlock.lock () ؛ جرب {if (poolsize <mailmumpoolsize && runstate == running) t = addThread (firstTask) ؛ } أخيرًا {mainlock.unlock () ؛ } if (t == null) return false ؛ T.Start () ؛ العودة صحيح. }يصف الرمز أعلاه أنه إذا كان عدد تجمعات مؤشرات الترابط الحالية أقل من MaximumpoolSize ، فسيتم إنشاء مؤشر ترابط لتنفيذ المهمة.
5. قائمة انتظار البركة الخيطية
هناك 3 أنواع من قوائم قوائم تجمع الخيوط:
الالتزام المباشر: الخيار الافتراضي لقوائم العمل هو متزامن ، والذي يقدم المهام مباشرة إلى المواضيع دون الاحتفاظ بها. هنا ، إذا لم يكن هناك مؤشر ترابط متاح لتشغيل المهمة على الفور ، فإن محاولة وضع قائمة انتظار المهمة ستفشل ، وبالتالي بناء مؤشر ترابط جديد. تتجنب هذه السياسة الأقفال عند التعامل مع مجموعات الطلبات التي قد يكون لها تبعيات داخلية. عادة ما تتطلب التقديمات المباشرة من Maximumpoolsizes غير محدود لتجنب رفض المهام المقدمة حديثًا. تتيح هذه الاستراتيجية المواضيع غير المحدودة أن يكون لها إمكانية النمو عندما تصل الأوامر بشكل مستمر بمتوسط يمكن أن يتعامل معه قائمة الانتظار.
قائمة انتظار غير محدودة: استخدام قائمة انتظار غير محدودة (على سبيل المثال ، LinkedBlocking دون سعة محددة مسبقًا) سيؤدي إلى انتظار مهام جديدة في قائمة الانتظار عندما تكون جميع مؤشرات الترابط CorePoolsize مشغولة. وبهذه الطريقة ، لن يتجاوز الخيط الذي تم إنشاؤه CorePoolsize. (قيمة maximumpoolsize غير صالحة.) عندما تكون كل مهمة مستقلة تمامًا عن المهام الأخرى ، أي أن تنفيذ المهمة لا يؤثر على بعضها البعض ، فهو مناسب لقوائم الانتظار غير المحدودة ؛ على سبيل المثال ، في خادم صفحة الويب. يمكن استخدام هذا الانتظار للتعامل مع طلبات الانفجار المؤقت ، وتتيح هذه الاستراتيجية أن يكون لها مؤشرات الترابط غير المحدودة إمكانية النمو عند وصول الأوامر باستمرار تتجاوز المتوسط الذي يمكن أن يتعامل معه قائمة الانتظار.
قائمة الانتظار المحددة: عند استخدام محدودية Maximumpoolsize ، تساعد قوائم الانتظار المحددة (مثل ArrayBlockingQueue) على منع استنفاد الموارد ، ولكن قد يكون من الصعب ضبطها والتحكم فيها. قد يحتاج حجم قائمة الانتظار وحجم حمام السباحة إلى تبادل بعضهما البعض: يمكن أن يؤدي استخدام قوائم الانتظار الكبيرة والتجمعات الصغيرة إلى تقليل استخدام وحدة المعالجة المركزية ، وموارد نظام التشغيل ، وتبديل السياق ، ولكن يمكن أن يؤدي إلى انخفاض يدوي في الإنتاجية. إذا تم حظر المهام بشكل متكرر (على سبيل المثال ، إذا كانت حدود I/O) ، فقد يحدد النظام وقتًا لمزيد من المواضيع أكثر مما تسمح به. عادةً ما يتطلب استخدام قوائم الانتظار الصغيرة حجمًا أكبر للسباحة ولديه استخدام أعلى وحدة المعالجة المركزية ، ولكن قد يواجه النفقات العامة غير المقبولة ، مما قد يقلل أيضًا من الإنتاجية.
دعنا نتحدث عن قائمة انتظار تجمع الخيوط أدناه ، مخطط بنية الفصل هو كما يلي:
1) متزامن
قائمة الانتظار تتوافق مع التقديم المباشر المذكور أعلاه. بادئ ذي بدء ، فإن Synchronousqueue غير محدود ، مما يعني أن قدرتها على تخزين الأرقام غير محدودة. ومع ذلك ، نظرًا لخصائص قائمة الانتظار نفسها ، وبعد إضافة عناصر ، يجب أن تنتظر أن تأخذها مؤشرات ترابط أخرى قبل أن تتمكن من الاستمرار في إضافتها.
2) LinkedBlockingqueue
قائمة الانتظار يتوافق مع قائمة الانتظار غير المحدودة أعلاه.
3) arrayblockingqueue
قائمة الانتظار يتوافق مع قائمة الانتظار المحددة أعلاه. ArrayBlockingQueue لديه المؤسسات الثلاثة التالية:
ArrayBlockingQueue (السعة int) {هذا (السعة ، خطأ) ؛ } ArrayBlockingQueue (السعة int ، معرض منطقي) {if (السعة <= 0) رمي جديد alfictalargumentException () ؛ this.items = (e []) كائن جديد [السعة] ؛ قفل = جديد reentrantlock (عادلة) ؛ notempty = lock.newcondition () ؛ notfull = lock.newcondition () ؛ } ArrayBlockingQueue (السعة int ، معرض منطقي ، جمع <؟ يمتد e> c) {this (السعة ، عادلة) ؛ إذا (السعة <c.size ()) رمي جديد غير unalfalArgumentException () ؛ لـ (iterator <؟ تمديد e> it = c.iterator () ؛ it.hasNext () ؛) add (it.next ()) ؛ }دعونا نركز على هذا المعرض. يمثل Fair استراتيجية المنافسة لخيوط الوصول إلى قائمة الانتظار. عندما يكون صحيحًا ، يتوافق قوائم إدخال المهام لقواعد FIFO. إذا كان خطأ ، يمكنك "قطع قائمة الانتظار". على سبيل المثال ، إذا كان هناك العديد من المهام في قائمة الانتظار الآن ، فقد أكمل مؤشر ترابط المهمة وتأتي مهمة جديدة. إذا كانت هذه المهمة ، فلا تحتاج إلى قائمة انتظار في قائمة الانتظار. يمكنك قطع قائمة الانتظار مباشرة ثم تنفيذها. كما هو مبين في الشكل أدناه:
6. استراتيجية تنفيذ رفض تجمع الخيوط
عندما يصل عدد مؤشرات الترابط إلى الحد الأقصى لقيمة ، لا تزال المهام تأتي في هذا الوقت ، وفي هذا الوقت ، يجب أن أرفض قبول المهام.
يسمح ThreadPoolexecutor بتخصيص سياسات التنفيذ عند فشل إضافة مهمة. يمكنك استدعاء طريقة setRejectedExecutionHandler () لمجمع مؤشرات الترابط واستبدال السياسة الحالية بكائن DesideDexecutionHandler المخصص. تتمثل استراتيجية المعالجة الافتراضية التي يوفرها ThreadPoolexecutor في التخلص مباشرة من معلومات الاستثناء ورميها مباشرة في نفس الوقت. يوفر Threadpoolexecutor 4 سياسات موجودة ، وهي:
threadpoolexecutor.abortpolicy: يشير إلى أن المهمة مرفوضة وإلقاء استثناء. رمز المصدر كما يلي:
تنفيذ AbortPolicy الفئة الثابتة العامة refectedExecutionHandler { /*** ينشئ <tt> abortpolicy </tt>. * / Public AbortPolicy () {} / *** رمي دائمًا DesjectedExecutionException. * param r المهمة التي تم تشغيلها المطلوبة بتنفيذها * param e المنفذ الذي يحاول تنفيذ هذه المهمة * throws rejectedExecutionException دائمًا. */ public void rejectedExecution (Runnable R ، ThreadPoolexecutor e) {رمي جديد rejectedExecutionException () ؛ // استثناء رمي}}threadpoolexecutor.discardPolicy: هذا يعني أن المهمة مرفوضة ولكن لا يتم إجراء أي إجراءات. رمز المصدر كما يلي:
تنفس الفئة الثابتة العامة DiscardPolicy ResjectedExecutionHandler { /*** ينشئ <tt> discardPolicy </tt>. * / discardPolicy () {} / *** لا يفعل شيئًا ، والذي له تأثير التخلص من المهمة r. * param r المهمة القابلة للتشغيل التي طلبت تنفيذها * param e المنفذ الذي يحاول تنفيذ هذه المهمة */ void public refectedExecution (runnable r ، threadpoolexecutor e) {} // رفض مباشرة ، ولكن لا تفعل شيئًا}threadpoolexecutor.callerrunspolicy: يشير إلى أن المهمة يتم رفضها ويتم تنفيذ المهمة مباشرة في مؤشر ترابط المتصل. رمز المصدر كما يلي:
أدوات CallerRunspolicy الفئة الثابتة العامة refectedExecutionHandler { /*** تنشئ <tt> callerrunspolicy </tt>. * / Public CallerRunspolicy () {} / ** * ينفذ المهمة R في مؤشر ترابط المتصل ، ما لم يتم إيقاف تشغيل المنفذ * ، وفي هذه الحالة يتم التخلص من المهمة. * param r المهمة القابلة للتشغيل المطلوبة بتنفيذها * param e المنفذ الذي يحاول تنفيذ هذه المهمة */ public void rejectedExecution (runnable r ، threadpoolexecutor e) {if (! // تنفيذ المهام مباشرة}}}threadpoolexecutor.discardoldestpolicy: هذا يعني أن المهمة الأولى في قائمة انتظار المهمة يتم تجاهلها أولاً ، ثم تتم إضافة المهمة إلى قائمة الانتظار. رمز المصدر كما يلي:
الطبقة الثابتة العامة DonsardoldestPolicy تنفس DesjectedExecutionHandler { /*** تنشئ <tt> decardoldestpolicy </tt> للمنفذ المعطى. */ public devondoldestpolicy () {} public void rejectedExecution (runnable r ، threadpoolexecutor e) {if (! // تجاهل المهمة الأولى في قائمة الانتظار E.execute (R) ؛ // تنفيذ مهمة جديدة}}}عندما تصل المهام بشكل مستمر ، سيتم استطلاع المهمة من قائمة الانتظار ثم يتم تنفيذ مهمة جديدة.
لخص
ما سبق هو شرح مفصل لمجموعة مؤشرات الترابط الخاصة بـ JDK التي قدمها المحرر. آمل أن يكون ذلك مفيدًا للجميع. إذا كان لديك أي أسئلة ، فيرجى ترك رسالة لي وسوف يرد المحرر على الجميع في الوقت المناسب. شكرا جزيلا لدعمكم لموقع wulin.com!