If that's what it means then why doesn't it say so? I find the question
ambiguous at best.
The question isn't ambiguous, neither is the answer, if you understand
synchronization. From your posts its clear that you are missing a clear
understanding of this, so I'll try to explain it.
First of all, lets go back to the original question, and the answer you
don't like.
"Which of these are plausible reasons why a thread might be alive, but
still not be running?"
b) The thread is waiting on a monitor for an object so that it may access
a certain member variable of that object.
The answer is clearly true. A thread *may* block waiting on a monitor for
an object. The fact that the answer says it's to "access a member
certain member variable" is there to put it into a real-world context.
It's also true that the thread doesn't have to block on that
synchronization object, it can just go ahead and access the member
variable (with all the bad consequences).
"Variables cannot be declared as synchronized." is also true. That is why
access is synchronized on the object itself, because the member variable
*cannot* be declared synchronized.
To explain, let's look at a very simple example.
Suppose we have a class :
class CountClass {
int count;
}
Now, further suppose we have a multi-threaded application with 2 threads
running, and that an instance of CountClass exists called total, which is
accessible to both threads.
Each thread wants to increment total.count, and uses this code:
total.count += 1;
which may look harmless enough but there's a serious problem lurking in
the background waiting to bite you when you least expect it.
What actually happens is that the value of total.count is taken from
memory into a register, the register is incremented and then written back
to memory. This happens in both threads.
If this bit of code runs in thread 1 first, followed by thread 2 there is
no problem, and count gets incremented by 2. But, threads are meant to be
able to run synchronously, and this is where the problem lies. If thread
1 loads total.count into a register and then thread 2 also loads it, but
before thread 1 has incremented and written it back, then they will both
generate the same result and total.count will be incremented by 1 rather
than 2.
What is necessary is to synchronize access to this member variable so
only 1 thread can update it. The simplest way would be to declare it as
synchronized:
synchronized int count;
but this isn't allowed, as stated in the answer, so we need another
mechanism.
Every object has a monitor which can be used for synchronization. What the
code ought to do is synchronize access to the object's member variable
using the object's monitor :
synchronized( total ) {
total.count += 1;
}
this is what b) refers to. Access to the member variable total.count is
being synchronized on total's monitor.
There are alternatives to this. You can synchronize on any object's
monitor, it doesn't have to be the object whose member variable you are
accessing:
synchronized( anotherObject ) {
total.count += 1;
}
would work just as well.
Also, you could protect count, and provide access via a syncrhonized
method:
class CountClass {
private int count;
public synchronized incrementCount() {
count += 1;
}
}
then in the thread, use the call :
total.incrementCount();
this is doing pretty much the same as the first alternative, as the method
incrementCount is synchronized on total's monitor.