Synchronized methods block the object from entering any other synchronized method of the object until the earlier one is finished.
In their example:
Synchronized function on Alphonse is called; Alphonse gets locked until completion.
Synchronized function on Gaston is galled; Gaston gets locked until completion.
Gaston calls synchronized function on Alphonse; it blocks until the lock is released.
Alphonse calls synchronized function on Gaston; it blocks until the lock is released.
Deadlock.
I wanted to make my engine multithreaded
Hopefully your little piece of example code above will change your mind.
You really want to AVOID MULTITHREADING inside your engine until you have already mastered many other areas of game development. Eventually you will start with using asynchronous methods and callbacks. Then you will come to making a single specific algorithm take advantage of multiprocessing when it is available.
Most experienced developers see a problem that suggests multithreading, cry on the inside, and then use it as an opportunity to either implement a naively asynchronous solution or implement a piece-wise sequential solution that avoids all the uncertainties of multiprocessing.
Writing correct solutions to problems that require serious use of multiprocessing is difficult. Usually it is easier to find alternative solutions than to find the subtle demons in buggy multiprocessing code.