Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to synchronize both method and object

So I have the following list which is accessed from multiple threads:

ArrayList<String> listOfString = Collections.synchronizedList(new ArrayList<String>());

I know that when I iterate through the list I have to synchronize like so:

synchronized(listOfString)
{
    for(String s : listOfString) System.out.println(s);

    listOfString.clear();
}

What about if I want to remove something, do I do this:

public void removeString(String s)
{
    listOfString.remove(s);
}

or this:

public synchronized void removeString(String s)
{
    listOfString.remove(s);
}
like image 380
Cheetah Avatar asked Mar 23 '23 22:03

Cheetah


1 Answers

As you said, the list is already synchronized, so your removeString method does not need to be synchronized too.

Note however that if one of your methods contains a non-atomic operation (say you want to check if your list contains something then modify the list accordingly), you might need to add another layer of synchronization.

Finally, you don't seem to have noticed that this method:

public synchronized void removeString(String s)

synchronizes on a different lock (it synchronizes on this). So back to the example I gave above, you would write it:

public void someMethod() {
    synchronized(listOfString) { //use the same lock!
        if(listOfString.size() == 123) {
            listOfString.add("lucky day");
        }
    }
}
like image 180
assylias Avatar answered Apr 24 '23 23:04

assylias