问题描述
我有一个对象,它是一个单例。此对象声明:
列表< Player> players = new ArrayList< Player>();
同样的对象也为这个arrayList指定了4个操作:
public List< Player> getPlayers(){
return player;
} //此方法的结果可以在另一个对象中用作迭代器(或者可以通过索引访问)
和
public void removePlayer(Player player){
players.remove );
}
public void addPlayer(Player player){
players.add(player);
}
public boolean isPresent(Player player){
if(players.constans(player)){...
}
现在在构造函数中我正在做这样的操作:
players = Collections.synchronizedList(new ArrayList< Player>());
但是什么是同步这些方法的正确方法。似乎如果我在另一个类中使用iterator,它仍然会通过并发修改异常。如果2个线程同时调用remove和contains方法,异常是否会发生?有很多线程访问单例,所以我想知道这样做的方法,以最小的性能打击。
解决方案
List list = Collections.synchronizedList(new ArrayList());
...
synchronized(list){
Iterator i = list.iterator(); //必须在同步块中
while(i.hasNext())
foo(i.next());
}
$ b包含
和remove
,您不应手动同步。我正在查看Collections
的源代码,它看起来像是为你:public boolean contains(Object o){
synchronized(mutex){return c.contains(o);}
}
synchronized(mutex){return c.remove(o);}
}
如果你必须自己做这个东西,它不会是一个同步列表。
I have an object which is a singleton. This object declares:
List<Player> players = new ArrayList<Player>();
The same object also specifies 4 operations on this arrayList:
public List<Player> getPlayers() { return players; } // the result of this method can be used in another object as an iterator (or maybe by index-access)
and
public void removePlayer(Player player) { players.remove(player); } public void addPlayer(Player player) { players.add(player); } public boolean isPresent(Player player) { if (players.constans(player)) {... }
Right now in the constructor I am doing it like that:
players = Collections.synchronizedList(new ArrayList<Player>());
But what is the CORRECT way to synchronize these methods. It seems like if I use iterator in another class, it will still through the concurrent modification exception. Does the exception happen if a 2 threads call at the same time the "remove" and "contains" method? There are many threads to access the singleton so I would like to know the method to do this with the minimum hit on performance.
解决方案The documentation answers your question.
List list = Collections.synchronizedList(new ArrayList()); ... synchronized(list) { Iterator i = list.iterator(); // Must be in synchronized block while (i.hasNext()) foo(i.next()); }
As for
contains
andremove
, you shouldn't have to synchronize manually. I'm looking at the source code ofCollections
and it looks like it does that for you:public boolean contains(Object o) { synchronized (mutex) {return c.contains(o);} } public boolean remove(Object o) { synchronized (mutex) {return c.remove(o);} }
It wouldn't be a synchronized list if you have to do this stuff on your own.
这篇关于java并发数组列表访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!