In Java, a block of code marked as synchronized can be executed by a single thread at a time. Since Java is a multi-threaded environment (it supports concurrency), it needs a synchronization mechanism to avoid issues specific to concurrent environments (for example, deadlocks and memory consistency).
A thread can achieve locks at the object level or at the class level.