3

For this simple synchronized statement:

public void addName(String name) {
    synchronized(this) { // line1
        lastName = name;
        nameCount++;
    }
    nameList.add(name);
}

It seems that two threads lets' say t1 and t2 can invoke the addName method at the same time, but once get the line commented as line1, only one thread can continue, which means other thread will have to suspended. Which means even the nameList is put outside the synchronized statement, it is guaranteed that the nameList will not be conflicted by multiple threads.

Is that true? If yes, so is there any difference between the following approach if nothing have to be done before the synchronized statement:

public void addName(String name) {
    synchronized(this) {  //line1
        lastName = name;
        nameCount++;

        nameList.add(name);
    }
}

Or:

public synchronized void addName(String name) {
        lastName = name;
        nameCount++;
        nameList.add(name);
}

I know exactly that

void synchronized add(){

}

is the same as:

void add(){
  synchronized(this){

  }
}

What confused me is that, in the addName example, I thought the execution order may like this:

t1:synchronized steatement
t1:nameList.add
t2:synchronized steatement
t2:nameList.add

Which means there is no execution change for other thread between the synchronized statement and the nameList.add. So there is no difference of putting the nameList.add inside our outside the synchronized block.

But in fact, the execution may looks like this as the answer by @JB Nizet:

t1:synchronized steatement
t2:synchronized steatement

t2:nameList.add
t1:nameList.add

Then putting the nameList outside or inside the block is important.

hguser
  • 35,079
  • 54
  • 159
  • 293

1 Answers1

4

The two last snippets are equivalent, but the first one is not.

In the first snippet, given that the addition to the list is not part of the synchronized block, two threads can execute this instruction concurrently. If the list is not thread-safe, then it's a problem.

It is also probably a problem even if the list is thread-safe, because the changes to the various parts of the state (the count, the last name and the list) are not made atomically. Other threads might thus see the new value for the last name, but not find this last name in the list.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Thank you I got it, I have thought that one thread will call the the `nameList.add` as soon as the synchronized statement completed, without any other thread can interleave. But in fact, the `nameList.add` can be accessed concurrently. – hguser Apr 12 '15 at 08:43