Locking on a class field synchronizes not on the field itself, but on the object assigned to it. So locking on a non-readonly
field makes it possible for the field’s value to change while a thread is in a block locked on the old value. That would allow a second thread, locked on the new value, to enter the block at the same time.
Locking on a readonly
field of a class which is not private
allows external code to lock the field, potentially interfering with synchronization of methods in that class.
Locking on a local variable or on a new instance undermines the synchronization: two different threads running the method in parallel would lock on two different object instances.
Locking on a string literal is even more dangerous: depending on whether the string is interned or not, different threads may or may not synchronize on the same object instance.
private string color = "red";
private void DoSomething()
{
lock (color) // Noncompliant; lock is actually on object instance "red" referred to by the color variable
{
//...
color = "green"; // other threads now allowed into this block
// ...
}
lock (new object()) // Noncompliant this is a no-op.
{
// ...
}
}