قائمة انتظار الحظر المحدودة التي لا يتم حظرها

StackOverflow https://stackoverflow.com/questions/1231378

  •  22-07-2019
  •  | 
  •  

سؤال

عنوان هذا السؤال يجعلني أشك في وجود هذا، ولكن لا يزال:

أنا مهتم بمعرفة ما إذا كان هناك تطبيق لـ Java BlockingQueue, ، وهو مقيد بالحجم، ولا يحظر أبدًا، بل يرمي استثناءً عند محاولة وضع عدد كبير جدًا من العناصر في قائمة الانتظار.

يحرر - أقوم بتمرير BlockingQueue إلى المنفذ، والذي أفترض أنه يستخدم طريقة add() الخاصة به، وليس العرض().يمكن للمرء كتابة BlockingQueue الذي يغلف BlockingQueue آخر ويفوض المكالمات لإضافة () إلى العرض ().

هل كانت مفيدة؟

المحلول

يحرر: بناءً على وصفك الجديد، أعتقد أنك تطرح السؤال الخطأ.إذا كنت تستخدم Executor، فمن المحتمل أن تحدد تخصيصًا RejectedExecutionHandler بدلاً من تعديل قائمة الانتظار.يعمل هذا فقط إذا كنت تستخدم ThreadPoolExecutor، ولكن إذا لم تكن تستخدمه، فمن الأفضل تعديل المنفذ بدلاً من قائمة الانتظار.

من رأيي أنه من الخطأ تجاوز العرض وجعله يتصرف مثل الإضافة.طرق الواجهة تشكل عقدًا.يعتمد رمز العميل الذي يستخدم قوائم الانتظار المحظورة على الأساليب التي تقوم بالفعل بما تحدده الوثائق.كسر هذه القاعدة يفتح أمام عالم من الأذى.ذلك، وهو غير أنيق.


ال يضيف() تقوم الطريقة الموجودة على BlockingQueues بذلك، ولكن لديها أيضًا يعرض() الطريقة التي تعتبر بشكل عام خيارًا أفضل.من وثائق العرض ():

يدرج العنصر المحدد في ذيل قائمة الانتظار هذه إذا كان ذلك ممكنا للقيام بذلك على الفور دون تجاوز سعة قائمة الانتظار ، والعودة إلى true عند النجاح وكاذبة إذا كانت هذه قائمة الانتظار ممتلئ.هذه الطريقة بشكل عام يفضل على طريقة الإضافة (E) ، والتي يمكن فشل في إدراج عنصر فقط بواسطة رمي استثناء.

يعمل هذا مع جميع قوائم الانتظار هذه بغض النظر عن التنفيذ المحدد (ArrayBlockingQueue، LinkedBlockingQueue وما إلى ذلك)

BlockingQueue<String> q = new LinkedBlockingQueue<String>(2);
System.out.println(q.offer("foo")); // true
System.out.println(q.offer("bar")); // true
System.out.println(q.offer("baz")); // false

نصائح أخرى

<اقتباس فقرة>   

ويمكن للمرء أن إرسال بريد BlockingQueue أن   يلتف آخر BlockingQueue و   المندوبين يدعو إلى إضافة () لتقديم ().

وإذا كان هذا هو المفترض أن يكون السؤال ... كان الجواب "نعم"، ولكن يمكنك أن تفعل ذلك أكثر بدقة من خلال خلق فئة فرعية أن يتجاوز الوظيفة (). الصيد الوحيد (في كلتا الحالتين) هو أن إصدار add لا يمكن أن يلقي أي فحص الاستثناءات التي ليست في الطريقة التي يتم تجاوز، لذلك بك "ستمنع" سوف استثناء تحتاج إلى أن تكون دون رادع.

وهذا أمر محزن، لا يمكنك منع، هناك الكثير من حالات الاستخدام حيث كنت ترغب في حظرها، الفكرة كلها من توفير الخاصة بهم يحدها قائمة الانتظار عرقلة إلى المنفذ ليس له معنى.

public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
            if (runState == RUNNING && workQueue.***offer***(command)) {
                if (runState != RUNNING || poolSize == 0)
                    ensureQueuedTaskHandled(command);
            }
            else if (!addIfUnderMaximumPoolSize(command))
                reject(command); // is shutdown or saturated
        }
    }

وهناك حالة استخدام بسيطة للحصول على الاستفسارات تنفيذها من ديسيبل مصدر دفعة واحدة (المنفذ)، وإثراء دفعة واحدة ووضعها في ديسيبل (المنفذ) آخر، هل تريد تنفيذ استعلامات فقط بأسرع ما يجري وضعها موضع ديسيبل آخر. وفي هذه الحالة، يجب أن المنفذ دست قبول المنفذ يحدها عرقلة حل المشكلة من الحفاظ الاقتراع والتحقق كم تم الانتهاء من تنفيذ المزيد من الاستفسارات.

عفوا أكثر، أرى ما تبقى تعليق:

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top