Conditional Queue
- Help build efficient and responsive state-dependent classes
- Conditional Variables are also called conditional queue. Why???
- every thread which call lock.wait(), will want to wait for thread to notify
- The lock object and the condition queue object must be the same
- Implementation Pattern:
void foo() throws InterruptedException {
synchronized (lock) {
while (!conditionPredicate()) {
lock.wait();
}
// do your logic
}
}- https://stackoverflow.com/questions/12551341/when-is-a-condition-variable-needed-isnt-a-mutex-enough
- https://stackoverflow.com/questions/65117449/why-is-condition-variable-also-called-condition-queue-if-it-is-not-implemented-a
wait(), notify() and notifyAll()
- They all must be called after holding the lock
- All of them throws
IllegalMonitorStateExceptionif current thread does not hold the lock on which they are called - Calling notify()/notifyAll() when no thread is waiting has no impact
- notify() notifies single thread and it is not deterministic which thread will be notified
- Thread States
- https://stackoverflow.com/questions/15680422/difference-between-wait-and-blocked-thread-states
- https://stackoverflow.com/questions/28378592/java-thread-state-transition-waiting-to-blocked-or-runnable
- wait()
- Current thread goes to
WAITINGstate - current lock is released
- The execution will resume from the same place where wait was called if it re-acquires the lock after getting notify signal
- Current thread goes to
- notify() / notifyAll()
- All waiting threads go to
BLOCKEDstate - diagrams on internet are wrong which says that they go to
RUNNABLE - At
BLOCKEDstate, All notified threads are competing equally to the threads who have not entered the synchronization block and waiting for the lock to be acquired
- All waiting threads go to
- https://stackoverflow.com/questions/2779484/why-must-wait-always-be-in-synchronized-block
- https://stackoverflow.com/questions/13249835/java-does-wait-release-lock-from-synchronized-block
- https://stackoverflow.com/questions/61562542/wait-and-notify-jmm-semantics
Condition Predicate
- Precondition that makes an operation state-dependent
- Example In Bounded Buffer:
- take(): “buffer is not empty”
- put(): “buffer is not full”
- If condition predicate is not true, the operation just waits
ReentrantLock
- Has
Conditionwhich has following methods:await()signal()signalAll()
Interview Qs
Spurious wakeup
- Sometimes threads can wakeup without explicit notify() or notifyAll() methods
- Happens from OS side
- This is the reason why while loop is used to check the condition again and again
- This while loop is also known as spin lock?
- https://stackoverflow.com/questions/1050592/do-spurious-wakeups-in-java-actually-happen
Missed signals
- Always use notifyAll() since if you use notify() and you have more than one threads waiting then it will cause missed signal
- See Risk of Threads
wait() vs sleep()
- wait is for unspecified time, sleep for some specified time
- wait releases the lock, sleep does not release the lock
- wait works on condition, sleep works on time elapsed
wait() vs wait(timeout)
- wait(timeout) waits for the specified time and resumes execution
- wait() waits indefinitely until notify signal is received