¿Cómo funciona la funcionalidad de sincronización en Java?

Desde que comencé a programar en Java, me he estado preguntando esto (alrededor de un año o dos). En C, debemos conocer los diferentes métodos para evitar correctamente el punto muerto entre subprocesos y, por lo tanto, hay muchas más opciones entre el método de sincronización.

Entonces, ¿qué pasa con Java? Cuando sincronizamos, ¿cómo evita poner el hilo en una situación de bloqueo? ¿Cómo funciona internamente? ¿Se evita el punto muerto porque sincronizamos en un nivel más alto que en C (o C ++)? ¿Alguna documentación sobre punto muerto y sincronización en Java?