سؤال

لدي مدير فئة سيتم الوصول إليها من قبل مؤشرات الترابط متعددة في نفس الوقت، أريد أن أعرف إذا فعلت ذلك بالطريقة الصحيحة؟
وأعتقد أيضا أنني بحاجة إلى refectfoo لتكون ذرية، لكنني لست متأكدا

public class Manager
{
    private ConcurrentHashMap<String, Foo> foos;
    //init in constructor

    public RemoveFoo(String name)
    {
        Foo foo = foos.Get(name);
        foo.RemoveAll();
        foos.Remove(name);
    }

    public AddFoo(Foo foo)
    {...}
}

public class Foo
{
    private Map<String,Bar> bars;
    //intialize it in constructor

    //same for RemoveBar
    public void AddBar(Bar bar)
    {
        synchronized(this)
        {
            bars.put(bar.id, bar);
        }
    }

    public void RemoveAll()
    {
        synchronized(this)
        {
            //some before removall logic for each one
            bars.remove(bar.id, bar);
        }
    }

}

public class Bar
{}
هل كانت مفيدة؟

المحلول

RemoveFoo يمكن أن تكون مشكلة. أقترح استخدام:

Foo foo = foos.remove (name);
if (foo != null) foo.removeAll();

في حين أن. هذا يتأكد من أن الخريطة لا تتغير بين get() و remove().

في Foo, ، يكفي مزامنة bars بدلا من المثال كله. لكن هذا مجرد تحسين بسيط.

نصائح أخرى

لا تحتاج إلى طرق متزامنة كما كنت تستخدم Concurrenthashmap، ومع ذلك كن على علم بذلك Foo foo = foos.Get(name) يمكن إرجاع null حيث يمكن بالفعل إزالة مؤشر ترابط آخر الإدخال من الخريطة.

يمكن إعلان الأعضاء كما Map<String, Foo> foos, ، ولكن يجب الاحتهية foos = new ConcurrentHashMap<String, Foo>;

يعلن RemoveFoo(String) كما synchronized:

public synchronized void RemoveFoo(String name) {
    …
}

أيضا، أن ينصح بما يلي:

  • يجب أن تكون أسماء الأسلوب حالة صغيرة، على سبيل المثال removeFoo بدلا من RemoveFoo. وبعد هذا ليس ج #. :)
  • كل طريقة تحتاج نوع المرتج: public removeFoo() ليس إعلان طريقة صالحة، يجب أن يكون public void removeFoo().

إذا كنت تستخدم concurrenthmap في فو مثل

private Map<String,Bar> bars = new ConcurrentHashMap<String, Bar>();

ربما يمكنك الاستغناء عن المزامنة في فو كذلك.

لست متأكدا مما ستفعله على Foo وبار، ولكن يبدو وكأنه نمط من الكتب.

إذا لم يتم الرجوع إليها من قبل الآخرين، ما عليك سوى استدعاء FOOS.REMOVE (الاسم)؛ واترك محرك GC يعالج الكتب.

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