Buenas!
La palabra reservada synchronized se usa para indicar que ciertas partes del código, (habitualmente, una función miembro) están sincronizadas, es decir, que solamente un subproceso puede acceder a dicho método a la vez.
Cada método sincronizado posee una especie de "llave" que puede cerrar o abrir la puerta de acceso. Cuando un subproceso intenta acceder al método sincronizado mirará a ver si la llave está echada, en cuyo caso no podrá accederlo. Si método no tiene puesta la llave entonces el subproceso puede acceder a dicho código sincronizado.
En este caso el objeto lock hace de llave, y el código que hay dentro es el código sincronizado para que solo puede ser accedido por un subproceso a la vez.
En este ejemplo que pones también se hace uso de wait() y notify() para dormir y despertar hilos de ejecución. Este tutorial te puede servir de ayuda:
http://www.chuidiang.com/java/hilos/wait_y_notify.php