Let’s imagine someone synchronizes a method returning an int:
int whatever = 33;
...
public synchronized int getWathever() {
return this.whatever;
}
We know from Java specs that ints are modified atomically. Hence, the synchronized statement is not necessary.
Will the compilers remove/optimize it?
No, that simply is not possible. If the compiler and the JVM were to do so, it is likely that the constraints set by the Java programming language memory model would be violated.
More specifically, the synchronization order order stated in the Java Language Specification would be violated. If a compiler or a JVM* were to remove any “unwanted” synchronizations, then any further optimizations performed would violate any assumptions placed by a developer on the synchronization order (and the happens-before) relationship. In your specific case, any write to the integer will happen before the read, in a compiler/JVM that obeys the Java memory model.
A compiler/JVM that removes the synchronizations would simply result in an environment where the memory model is violated. For example, method in-lining could be performed without the compiler/JVM placing a memory barrier before the read of the integer value, thereby allowing for stale values to be read from a cached value.
* Note, the reference to the compiler/JVM duo is intentional. A compiler will only emit bytecode that complies with the JLS; a JVM could simply have a bug where the requirements of the memory model could still be violated. For the sake of completeness of the memory model, both the compiler and the JVM should comply with the requirements set by the memory model.