Synchronizing on a class field synchronizes not on the field itself, but on the object assigned to it. So synchronizing on a non-final
field makes it possible for the field’s value to change while a thread is in a block synchronized on the old value. That would allow a second thread,
synchronized on the new value, to enter the block at the same time.
The story is very similar for synchronizing on parameters; two different threads running the method in parallel could pass two different object instances in to the method as parameters, completely undermining the synchronization.
private String color = "red"; private void doSomething(){ synchronized(color) { // Noncompliant; lock is actually on object instance "red" referred to by the color variable //... color = "green"; // other threads now allowed into this block // ... } synchronized(new Object()) { // Noncompliant this is a no-op. // ... } }
private String color = "red"; private final Object lockObj = new Object(); private void doSomething(){ synchronized(lockObj) { //... color = "green"; // ... } }