onitor it simply waits, in a queue of other threads trying to acquire the same monitor, until the monitor is available.
When the thread that has the monitor is finished it has to explicitly exit or release the monitor. Of course the monitor is implemented in such a way that the sort of problems described with simple locking on a flag cannot happen – acquiring a monitor is an atomic operation – however there are other things that can go wrong as we will see.
The first big problem that confronts any programmer wanting to use a monitor is – which object to use for locking. Remember every object has a monitor and so can provide a unique lock restricting access to a resource.
At this point you need to focus on the fact that in many ways it is the code which accesses the resource which is locked and not the resource.
That is, suppose we have a block of code that manipulates a global variable. We clearly don’t want this code to be active on more than one thread at a time so we acquire the lock at the start of the code and release it at the end of the block.
If there are multiple different blocks of code that access the same resource then each of these blocks have to be written to acquire the lock at the start of the code and release it at the end.
You can now see that whatever object you use to provide the lock it has to be accessible to all of the blocks of code that need to use it. The object that you lock on also has to be a fairly obvious one for the job and it shouldn’t be used, by accident, by another block of code to restrict access to another resource.