本文介绍了java并发数组列表访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个对象,它是一个单例。此对象声明:

 列表< 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方法,异常是否会发生?有很多线程访问单例,所以我想知道这样做的方法,以最小的性能打击。

解决方案

文档可以解答您的问题。 / a>



  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 and remove, you shouldn't have to synchronize manually. I'm looking at the source code of Collections 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并发数组列表访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 18:12