3
votes

Suppose I have two threads. Thread1 is accessing a synchronized method, and at the same time, Thread2 is accessing another synchronized method of the same object. As what I know, Thread2 should wait till Thread1 finish its task. My question is, is Thread2 on the object's waiting thread list? It seems so for me, but Thread2 doesn't call wait() method, then as a logic result, it shouldn't on the object's waiting thread list. If it's not on the object's waiting thread list, what's the status of Thread2?

2

2 Answers

2
votes

When Tread2 is waiting for Thread1 to release the intrinsic lock held by Thread1, its blocked until the intrinsic lock becomes available (as in, u released by the executing thread, Thread1). So, in summery, Thread2 is waiting for the lock to be released, so it can acquire it.

Now, when a thread calls wait(), it must already hold the intrinsic lock. A call to wait() then releases the lock, and puts the thread in a waiting state, where its waiting for a signal from notify() or a notifyAll() to continue execution.

So, the two scenarios are different, the former is about execution implicitly being blocked until resource(the lock) becomes available. While the later is about explicitly releasing the a already held lock, and then waiting for a signal that its time to re-acquire the lock and continue.

0
votes

There is a distinction between those two scenarios, as you are right to note.

When a thread tries to run a synchronized block, but some other thread holds the monitor's lock, the incoming thread is blocked, until the lock is released, and granted to it.

For a thread to call wait(), it must already hold the monitor's lock (this is a relevant difference). Besides, calling wait() puts the thread waiting (releasing the lock), usually until it is notified by some other thread.

The usually above should be always, in an ideal scenario, but, as specified in the Java documentation, a phenomenon called spurious wakeup may occur, making the waiting thread wake up for no apparent reason. That's why the waiting conditions should be enclosed in a while statement, instead of an if. Example:

synchronized (this) {
    while (x < 0) { wait(); }
}

Instead of:

synchronized (this) {
    if (x < 0) { wait(); }
}