簡體   English   中英

Java線程安全代碼+原子方法問題

[英]java thread safe code + an atomic method question

我有一個可以同時被多個線程訪問的類管理器,我想知道我是否做對了嗎?
我也想我需要RemoveFoo是原子的,但是我不確定

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
{}

使用ConcurrentHashMap時不需要同步方法,但是請注意Foo foo = foos.Get(name)可能返回null,因為另一個線程可能已經從映射中刪除了該條目。

成員可以聲明為Map<String, Foo> foos ,但必須foos = new ConcurrentHashMap<String, Foo>;foos = new ConcurrentHashMap<String, Foo>;

RemoveFoo可能有問題。 我建議使用:

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

代替。 這樣可以確保在get()remove()之間映射不會改變。

Foo ,足以在bars而不是整個實例上進行同步。 但這只是次要的優化。

聲明RemoveFoo(String)為已synchronized

public synchronized void RemoveFoo(String name) {
    …
}

另外,請注意以下幾點:

  • 方法名稱應小寫,例如removeFoo而不是RemoveFoo 這不是C#。 :)
  • 每個方法都需要一個返回類型: public removeFoo()不是有效的方法聲明,它必須是public void removeFoo()

如果您在Foo中使用並發HashMap

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

也許您也可以取消Foo中的同步。

我不確定您將在Foo和Bar上做什么,但是它看起來像是釋放模式。

如果其他人未引用它們,則只需調用foos.Remove(name);。 並讓GC引擎處理釋放。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM