In page 72 of Release It! Michael Nygard says:
In Java, it is possible for a subclass to declare a method synchronized that is un-synchronized in its superclass or interface definition. Object-oriented purists will tell you that this violates the Liskov Substitution principle. They are correct.
What contract is being broken here? Just because a method call does not have synchronized on it does not mean it will not block. If that method call does any IO, database access, logging or even reading configuration it will need to synchronize. Since java makes no guarantee that any method call will execute in finite time, there is no contact to be broken. In fact the Java license explicitly forbids use of java in realtime systems. And only realtime programming languages put upper bounds on the time taken by a given operation.
Turning it around it would be nice at have a way of annotating a method in java to say that it is a pure function. Such a method would only do computation on its inputs and would not do any IO or access shared state. Of course it should be able to call other pure functions. That would be a nice development feature to have, and it would be a contract one would apply the Liskov Substitution principle to.
Having defined and proved a given method is a pure function, the JVM cannot guarantee that it
won’t block. The thread could be suspended indefinitely by the operating system scheduler, or a memory access can stall or even require a memory page to be read from a distant slow disk.
To my mind it makes sense include the general blocking behavior of a class in it’s contract, but that’s not the same as saying that introducing synchronized is breaking the contract.