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.
private String color = "red";
private void doSomething(){
synchronized(color) { // lock is actually on object instance "red" referred to by the color variable
//...
color = "green"; // Noncompliant; other threads now allowed into this block
// ...
}
}
private String color = "red";
private final Object lockObj = new Object();
private void doSomething(){
synchronized(lockObj) {
//...
color = "green";
// ...
}
}