Are there cases where wait and notify are the only solution or should be used only when building higher-level structures?
They should be used only when building structures of a higher level. If you have a case where existing higher-level constructs do not solve your problem, you do not want to return to wait / notify; you want to create a higher level design that solves your problem. You can implement it with wait / notify.
For example, I once had a problem that required the simultaneous execution of a set of tasks with hierarchical dependencies, where the dependency conditions included a combination of compounds ("and") and disjunctions ("or"). That is, there were cases when one task condition was "Task A has been completed and task B has been set," cases where "Task A or task B" was performed, and various combinations of these (for example, "Task A - and either task B is executed, either task C ").
So, I wrote a small utility library that provided an interface for clients to send collections of tasks annotated by their conditions, sent these tasks to Executor as soon as their preconditions were fulfilled, and monitored the completion of the task to start a new acceptable task. Some of them were implemented using java.util.concurrent (mainly Executor and Semaphore ), but other parts are involved using wait / notify (the coordinator stream is notified of the completion of the task with wait / notify).
Thus, the code turned out to be much easier to understand and troubleshoot, and then we found other applications for the same task coordinator library.
source share