سؤال

لديّ قطعة رمز أراجعها (باستخدام FindBugs).

public class MyClass{
...
private BlockedQueue q = new LinkedBlockingQueue<MyData>(1000);
private static final batchSize = 1000;

public boolean testMethod(){
    boolean done = false;
    synchronized(q){
       if(q.size == batchSize){
         q.notify();
         done = true;
       }
    }
    return done;

}

عندما أقوم بتشغيل FindBugs على قطعة الكود هذه ، فإنه يشكو من ذلك -

تنفذ هذه الطريقة مزامنة كائن يمثل مثيلًا لفئة من حزمة java.util.concurrent (أو فئاته الفرعية). تحتوي مثيلات هذه الفئات على آليات التحكم في التزامن الخاصة التي تتميز بعدم التوافق مع استخدام الكلمة الرئيسية المتزامنة.

إذا قمت بتعليق قطعة الكود المتزامن synchronized(q){, ، يشكو -

تستدعي هذه الطريقة Object.Notify () أو Object.NotifyAll () دون حمل قفل على الكائن بوضوح. إن استدعاء الإخطار () أو إخطار () بدون قفل سيؤدي إلى إلقاء القفل غير القانوني

كيف يمكنني تنفيذ هذه الطريقة بحيث تمرر التحقق من صحة FindBugs؟ هل التنفيذ أعلاه صحيح للإخطار في حالات الطبقات المتزامنة؟

شكرًا لك.

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

المحلول

notify() يذهب مع wait() ولا ينبغي استخدامه مع فئات من java.util.concurrent.

يستخدم Plockingqueue آليات داخلية لمنع على أ put() إذا لم يكن هناك مساحة لمزيد من العناصر أو poll() إذا لم يكن هناك عنصر للاستهلاك. ليس عليك أن تهتم بهذا.

نصائح أخرى

الخطأ الأول هو أنه يجب ألا تستخدم عناصر تحكم التزامن البدائي على فئات java.util.concurrent (مثل blockingqueue).

بشكل عام ، هذه ممارسة جيدة لأنها تعتني بمزامنة لك. أتصور أن هناك طريقة أفضل لحل مشكلتك في متناول اليد. ما هي المشكلة الفعلية التي تحاول حلها؟

يحدث الخطأ الثاني بسبب حقيقة أنه يجب عليك امتلاك قفل/شاشة كائن (عن طريق تخزينه) للاتصال بالانتظار/الإخطار/الإخطار عليه

blockingqueue هو المزامنة كائن - ينسق تدفق التحكم في مؤشرات الترابط بناءً على حالتها وبالتالي تحكم تدفق خيوط المنتج/المستهلك بسبب يأخذ و وضع قم بحظر حتى تدخل قائمة الانتظار إلى الحالة المطلوبة (ليست فارغة أو غير ممتلئة).

كما تفترض الممارسة الجيدة في برمجة التزامن أن الانتظار والإخطار يتم وضعه أثناء حلقة.

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