[英]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.