Защо методът wait() работи без notify()?

Страхотно благодаря предварително!

Имах проблеми със синхронизирането на 2 нишки: основна и нишка, която се извиква от StepRunner.java. Просто имам нужда от това, че резултатът от итерацията се показва преди началото на следващата итерация.

Какво искам:

Please enter step number [1, 2, 3 or 4] or 5 for exit: 2
Please enter natural value for factorial computing: 2
2! = 2
Please enter step number [1, 2, 3 or 4] or 5 for exit:

Какво не искам:

Please enter step number [1, 2, 3 or 4] or 5 for exit: 2
Please enter natural value for factorial computing: 2
Please enter step number [1, 2, 3 or 4] or 5 for exit: 2! = 2

За него имам синхронизиран блок в StepRunner.java:

public void run() {
        thread.start();
        synchronized (thread) {
            try {
                while (thread.isAlive()) { /**Loop is an Oracle's recommendation*/
                    thread.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

Но защо методът wait() работи правилно без метод notify() на което и да е място от моя код?


person Dmitry Bilko    schedule 28.03.2014    source източник
comment
Проверихте ли дали цикълът изобщо се изпълнява? Това е само предположение, но може би нишката поддържа собствен монитор (или може би планировчикът го прави) и по този начин синхронизираният блок се изпълнява само след като нишката приключи и вече не е жива.   -  person Thomas    schedule 28.03.2014
comment
Когато една нишка умре, тя се уведомява.   -  person Sotirios Delimanolis    schedule 28.03.2014


Отговори (1)


Javadoc на Thread гласи че Thread.notifyAll() се извиква вътрешно, когато нишката приключи:

Тази реализация използва цикъл от this.wait извиквания, обусловени от this.isAlive. Когато нишката приключи, се извиква методът this.notifyAll. Препоръчва се приложенията да не използват изчакване, уведомяване или notifyAll в екземпляри на Thread.

Както можете да видите, не се препоръчва използването на тази функция, вашият код може да бъде пренаписан, както следва:

thread.start();
try {
    thread.join();    
} catch (InterruptedException e) {
    e.printStackTrace();
}

Предвид факта, че това изявление се появи само в Java 7 javadoc и се препоръчва да не се използва тази функционалност, изглежда, че това поведение е било детайл от изпълнението на Thread клас, но хората започнаха да разчитат на него, така че авторите на езика трябваше документирайте го.

person axtavt    schedule 28.03.2014