Contract-based synchronization of multi-threaded Java programs