The above is the so-called calling notifyAll to trigger the run() from a non-Thread object. And it is actually working. But I am just confused by the following statement from a reliable resource:

If you need to call notifyAll() from within a non-synchronized method, then you must first obtain a lock on the object's monitor. If you don't, an exception will be generated when an attempt is made to call the method in question.

1)My question, if this is true, why does the cancelSearch() work?

2)Now call the notifyAll() from a Thread obect, such as

public class LockTip extends Thread {

public void run() {
while (true) {
try {
notifyAll();
}

The statement reads: This code will compile and run, but the first time there's an attempt to execute notifyAll() methods, an exception will be thrown:

java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:426)
at LockTip.run(LockTip.java:18)

To fix this problem, you have two options: add the keyword synchronized to the method definition or synchronize on the "this" keyword.

--My comment: Based on the 1) and 2) above, it made me believe that call notifyAll() from a non-Thread object, no need to do the synchronized to the method definition or synchronize on the "this" keyword; while calling the notifyAll() from a Thread object, I do need to do either synchronized to the method definition, or synchronize on the "this" keyword.

If my question does not sound confusing, please help me to understand this concept the correct way.