I don't get an error, but the Thread waits forever.
Yup, it does indeed. The problem is that run() method in Timer is synchronized, which means it holds the lock all the time and never releases it, so TimerTest never has a chance to get it, so it just waits. Instead of synchronizing the whole method you have to narrow the synchronized block, so the Timer thread would release the lock from time to time.
What you need is something like this (and remove synchronized from method declaration)