Locking is not magic, and must be used together. If I want the changes of some mutable object to not accidentally fall or be damaged by several threads, then I need to make sure that I only make changes to the object in the lock block.
The only thing that provides blocking is that any other code that is blocked on the same object does not work on other threads simultaneously, it is just syntactic sugar for receiving and issuing a mutex.
lock(x) // acquire mutex associated with x, or wait until it becomes available { // do stuff } // release mutex associated with x
Edit: MSDN lock details () are very important for anyone interested.
source share