Java List Access

I have an object that is singleton. This object declares:

List<Player> players = new ArrayList<Player>(); 

The same object also indicates 4 operations on this array list:

 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 this:

 players = Collections.synchronizedList(new ArrayList<Player>()); 

But what is the CORRECT way to synchronize these methods. It seems that if I use an iterator in another class, it will still be through a parallel modification exception. Does an exception occur if two threads simultaneously call the delete and contain methods? There are many threads to access singleton, so I would like to know how to do this, with minimal impact on performance.

+4
source share
2 answers

The documentation answers your question.

It is imperative that the user manually synchronizes the returned list when iterating over it:

 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 do not need to sync manually. I am looking at the source code for Collections , and it looks like it does this for you:

  public boolean contains(Object o) { synchronized (mutex) {return c.contains(o);} } public boolean remove(Object o) { synchronized (mutex) {return c.remove(o);} } 

This will not be a synchronized list if you have to do it yourself.

+11
source

If you do not plan to update it, often use CopyOnWriteArrayList , otherwise the @tieTYT clause works.

You can also manage this yourself by returning a copy of the list instead of the actual list in getPlayers . (If you are using Collections.synchronizedList )

 public List<Player> getPlayers(){ synchronized(list){ Collections.unmodifiableList(new ArrayList<Player>(list)); } } 

This has the side effect of an outdated list after adding / removing is complete

Edit: Theft of Grzegorz's offer for unmodifiableList

+6
source

Source: https://habr.com/ru/post/1490773/


All Articles