views:

37

answers:

1

This is my first time using the synchronized keyword, so I am still unsure of how it exactly works. I have a list that I want to be accessed by multiple threads so I do this:

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

Now, I want to make sure that I am not calling players.add() at the same time as players.get(), so I think i should use synchronized statements (methods A and B could be called at the same time):

public void A() {
    synchronized(players) {
        players.add(new Player());
    }
}

public void B(String msg) {
    synchronized(players) {
        for(int i = 0;i<players.size();i++) {
            players.get(i).out.println(msg);
        }
    }
}

Is this the correct procedure? If not, what should I do instead?

+2  A: 

Provided you only access the list through the object returned by synchronizedList then access should be thread-safe, though note that you may need to used synchronized blocks for compound actions like iterating through the list or making actions and decisions based on multiple calls into the list (for example, getting a value making a decision then adding a value).

So in your example A() doesn't need the synchronized block, but B() might if you don't want the list to be changed or be read by some other thread during the iteration. (In fact, by using the counter to iterate it is needed to prevent a race condition between the loop termination condition and another thread removing an item; other ways of iterating might not have this issue though).

fd
Wait, the synchronized block is only needed for multicall operations? I thought it was only getting the info.
TheLQ
Yes, if you want to protect the multiple calls from changes by other threads that could otherwise nip in between the two calls. Single operations are protected by the decoration that the Collections.synchronizedList() method provides.
fd
http://download.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html#synchronizedList%28java.util.List%29The javadoc seems to support always using a synchronized block when iterating.
George
The `List` interface isn't really rich enough to be used only with single operations. IMO, it is much clearer to avoid `synchronizedList` and use explicit locking.
Tom Hawtin - tackline