I don't understand the notion of threads competing for an object's lock in a single CPU environment. Let's assume that:
- threads W1, W2, and W3 are waiting for the object's lock (they invoked wait() on it) - threads B1, B2 and B3 are blocked waiting for the object's lock (they tried executing some synchronized code of the object) - some thread who owns the object's lock invokes notifyAll() on the object and releases the lock (exits synchronized code);
The result is that
- threads W1, W2, and W3 get out of the waiting state and get runnable - threads B1, B2 and B3 get out of the blocked state and get runnable
The API (1.4.2, the explanation of the Object's wait(long timeout)) says that:
The thread is then removed from the wait set for this object and re-enabled for thread scheduling. It then competes in the usual manner with other threads for the right to synchronize on the object;
So according to the API, all these runnable threads start competing for the object's lock, but how? Does not the scheduler pick a thread to run according to its implementation (and it does not care about whether or not some threads want to acquire an object's lock), which thread simply gets the lock ? Is that competing? Did I go wrong somewhere?
So the running thread gets the object's lock; if then it exits the running state (but retains the lock) and thread W1 gets into running state, what happens? He can't obtain the object's lock, so it exits the running state and it goes into blocked state ? And likewise for the other runnable threads that need the object's lock, when they get to run they enter the blocked state if they can't acquire the lock?
posted 14 years ago
After reading other posts (that by the way didn't get it right - thread - I think I've figured it out.
When notifyAll() is called for a certain object, all waiting threads (not blocked, but waiting) for that object are made runnable; then the scheduler selects one thread to run - lets assume it was one of the awakened threads - and that thread gets the lock. The other awakened threads become regular blocked threads (not waiting, but blocked) that become runnable when the object's lock becomes available again, and so on.