When you use the synchronized keyword with a block, like in the example above, you must specify an object to synchronize on. In the example, you are synchronizing on the object that the method was called on. You can also choose to synchronize on any other object.
Note that using the synchronized method on a method:
is just shorthand for the following:
So, when you use synchronized on a method, you are also synchronizing on the object that the method is called on.
When a method is synchronized, it also synchronizes on the object the method is called on (or the object's Class object if the method is static). The only difference between an explicit synchronized block on this and a synchronized method is that with the former, you can have code inside the method that's not synchronized. The call to nameList.add(name); from your code is a good example; this code will now be executed without any synchronization, whereas if the entire method would be synchronized it would be executed with synchronization.
Each Java object has a lock associated with it. When you use that object in a statement like this:
then in the first line, the first thread that executes the code will be able to get the lock of the object. In the last line, at the end of the block, it will release the lock. If another thread in the meantime also wants to execute the block, then in the first line it has to wait, because the lock is already taken by the first thread. The second thread will wait until the lock is released again by the first thread.