java 线程安全代码 +原子方法问题
我有一个类管理器将被多个线程同时访问,我想知道我是否以正确的方式进行了操作?
我也认为我需要 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
{}
I have a class Manager that is going to be accessed by multiple threads at the same time, I want to know if I did it the right way ?
also I think I need RemoveFoo to be atomic, but I'm not sure
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
{}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
当您使用 ConcurrentHashMap 时,您不需要同步方法,但请注意 Foo foo = foos.Get(name) 可能会返回 null,因为另一个线程可能已经从映射中删除了该条目。
成员可以声明为
Map; foos
,但必须缩写为foos = new ConcurrentHashMap;
You do not need synchronised methods as you are using a ConcurrentHashMap, however be aware that
Foo foo = foos.Get(name)
could return null as another thread could already have removed the entry from the map.Members can be declared as
Map<String, Foo> foos
, but must be initialsed asfoos = new ConcurrentHashMap<String, Foo>;
RemoveFoo
可能会出现问题。我建议使用:代替。这可以确保地图在
get()
和remove()
之间不会发生变化。在
Foo
中,在bars
上同步而不是整个实例就足够了。但这只是一个小优化。RemoveFoo
could be problematic. I suggest to use:instead. This makes sure that the map doesn't change between
get()
andremove()
.In
Foo
, it's enough to synchronize onbars
instead of the whole instance. But that's just a minor optimization.将
RemoveFoo(String)
声明为synchronized
:另外,请注意以下事项:
removeFoo
而不是删除Foo
。这不是 C#。 :)public removeFoo()
不是有效的方法声明,它需要是public void removeFoo()
。Declare
RemoveFoo(String)
assynchronized
:Also, be advised of the following:
removeFoo
instead ofRemoveFoo
. This is not C#. :)public removeFoo()
is not a valid method declaration, it needs to bepublic void removeFoo()
.如果您在 Foo 中使用并发HashMap,如
private Map; bar = new ConcurrentHashMap();
也许您也可以取消 Foo 中的同步。
If you use a concurrentHashMap in Foo like
private Map<String,Bar> bars = new ConcurrentHashMap<String, Bar>();
maybe you can do away with the synchronization in Foo as well.
我不确定你要对 Foo 和 Bar 做什么,但它看起来像是一种解除分配的模式。
如果它们没有被其他人引用,只需调用 foos.Remove(name);并让 GC 引擎处理释放。
I am not sure what you are going to do on Foo and Bar, but it looks like a pattern of deallocation.
If they are not referenced by others, just call foos.Remove(name); and let GC engine handle the deallocation.