What does it mean to lock an object?

Every object instance in Java has a little piece of data hanging off of it called a "monitor lock." This is similar to a semaphore.

When you use the synchronized
keyword, the current thread attempts to obtain the monitor lock for the object in question (either "this" or the object named explicitly). If the lock is unavailable, because another thread has acquired it, then the current thread pauses indefinitely. When it wakes up again, it will have acquired the lock, and will retain it until the end of the code block where synchronized was used.

One confusing part is that the only thing that this lock locks is access to the lock itself. It does not control access to instance variables or method access in and of itself. Other threads can reach in and modify variables and call methods. If you want the lock to control access to variables, then you must explicitly use the synchronized keyword every single place in your code that accesses them.

A straightforward way to guarantee that no variable access happens without a lock is by making all your variables private and using synchronized on all your accessor/mutator methods (getFoo/setFoo).