Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> wait надо вызывать по отношению к чему? 
:(
    Опции темы
Dims
Дата 18.12.2007, 20:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1016
Регистрация: 21.11.2006

Репутация: 4
Всего: 11



Что конкретно делает wait()? Он приостанавливает поток по отношению к тому объекту, чей у него монитор или вообще? То есть, по отношению к чему нужно вызывать wait? Если просто вызвать wait, то он, как я понимаю, вызовется по отношению к тому экземпляру, в котором он вызван. То есть, конструкция

Код

synzhronized(a) {
...
wait()
...
}


в общем случае неправильна, потому что вызывает wait по отношению к this, а не к a?


PM MAIL   Вверх
W0LF
Дата 18.12.2007, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


alexander lonsky
***


Профиль
Группа: Участник
Сообщений: 1164
Регистрация: 9.2.2006
Где: Ukraine.Dnepropet rovsk

Репутация: нет
Всего: 20



wait() приостанавливает текущий поток и делает доступной эту критическую секцию другим потокам, а Thread.sleep() приостанавливает текущий поток и при этом так же лочит текущую крит. секцию

Добавлено через 7 минут и 15 секунд
кста, вот статья неплохая по многопоточности



Это сообщение отредактировал(а) W0LF - 18.12.2007, 20:52


--------------------
iOS developer
PM MAIL WWW Skype GTalk   Вверх
ivg
Дата 18.12.2007, 21:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Autonomous R&D
**


Профиль
Группа: Участник
Сообщений: 686
Регистрация: 8.2.2006
Где: Екатеринбург

Репутация: 33
Всего: 81



Цитата(W0LF @  18.12.2007,  20:49 Найти цитируемый пост)
и при этом так же лочит текущую крит. секцию

Вы заблуждаетесь, хотя .....  О какой крит. секции идёт речь?
PM MAIL   Вверх
Dims
Дата 18.12.2007, 23:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1016
Регистрация: 21.11.2006

Репутация: 4
Всего: 11



А что делает wait по отношению к объекту-подтипу Thread? Оно как-то реагирует на то, стоит поток или нет?
PM MAIL   Вверх
COVD
Дата 19.12.2007, 00:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Цитата

объекту-подтипу Thread? Оно.. 


терминология у вас какая-то, "научная", что-ли  smile 

Код

Object LOCK  = new Object();

synchronized(LOCK){//поток поставил флаг на обьекте "занято"!
    
    LOCK.wait();//поток остановился и ждет сигнала пробуждения notify или notifyAll. Флаг "занято" с обьекта LOCK убран, иначе другой поток не сможет сделать notify. Любой поток может зайти в блок и тоже встать на wait.

    doSomething();//поток пробудился и снова флаг "занято" на обьекте LOCK. Только один поток выполняет метод doSomething();
}
//поток вышел из блока и снял флаг "занято". 
//Если на LOCK в wait стояли другие потоки и была применена команда notifyAll то теперь они по-очереди работают. 
//notifyAll не гарантирует правильную очередность.



Это сообщение отредактировал(а) COVD - 19.12.2007, 00:24
PM MAIL   Вверх
Dims
Дата 19.12.2007, 00:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1016
Регистрация: 21.11.2006

Репутация: 4
Всего: 11



Цитата(COVD @  19.12.2007,  00:04 Найти цитируемый пост)
терминология у вас какая-то, "научная", что-ли  smile 

А как правильно сказать?

Ну я это понял. А что будет, если один поток вызовет wait по отношению к другому потоку? Не к какому-то объекту, а к самому потоку?
PM MAIL   Вверх
COVD
Дата 19.12.2007, 00:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Цитата

Ну я это понял. А что будет, если один поток вызовет wait по отношению к другому потоку? Не к какому-то объекту, а к самому потоку? 


я не пробовал   smile  Но ведь Thread - это тоже Object, значит у него есть наследованные методы wait и notify. Наверное как и любой другой обьект может использоваться, чтобы на нем "заснуть". Только зачем? Чтобы запутать кого-нибудь?

Добавлено через 12 минут и 13 секунд
Цитата

А как правильно сказать?


я просто с первой попытки не понял. 
Цитата

Оно как-то реагирует на то, стоит поток или нет


В смысле, Оно - это wait? Т.е. играет ли роль тип обьекта на котором вызывается wait()? Нет. Это должен быть инстанс Object. На нем ставится флаг, т.е. некоторая переменная устанавливается в true. Все обьекты эту переменную имеют. И она используется потоками которые к этому обьекту имеют доступ. 

Это сообщение отредактировал(а) COVD - 19.12.2007, 00:33
PM MAIL   Вверх
Dims
Дата 19.12.2007, 02:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1016
Регистрация: 21.11.2006

Репутация: 4
Всего: 11



Цитата(COVD @  19.12.2007,  00:29 Найти цитируемый пост)
я не пробовал   smile  Но ведь Thread - это тоже Object, значит у него есть наследованные методы wait и notify. Наверное как и любой другой обьект может использоваться, чтобы на нем "заснуть". Только зачем? Чтобы запутать кого-нибудь?

Мне кажется, я где-то видел, что при помощи wait по отношению к потоку ждали то ли его завершения, то ли приостановки.

Естественно, понятно, что будучи наследником Object-а, он наследует его свойства.

А вот ещё вопрос: чем отличается notifyAll? Насколько я понимаю, если потоки стоят в режиме ожидания, то даже если их толкнуть все, то задвигается всё равно только один, ведь монитор может получить только один.

PM MAIL   Вверх
W0LF
Дата 19.12.2007, 11:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


alexander lonsky
***


Профиль
Группа: Участник
Сообщений: 1164
Регистрация: 9.2.2006
Где: Ukraine.Dnepropet rovsk

Репутация: нет
Всего: 20



Цитата(ivg @  18.12.2007,  21:41 Найти цитируемый пост)
О какой крит. секции идёт речь? 

то, что в этом блоке
Код

synzhronized(a) {

}

называется критической секцией

Добавлено через 1 минуту и 51 секунду
Цитата(Dims @  19.12.2007,  02:13 Найти цитируемый пост)
А вот ещё вопрос: чем отличается notifyAll? Насколько я понимаю, если потоки стоят в режиме ожидания, то даже если их толкнуть все, то задвигается всё равно только один, ведь монитор может получить только один.

абсолютно верно, но не совсем все, а которые держит текущий объект-монитор. только какой из них первым будет - неизвестно


--------------------
iOS developer
PM MAIL WWW Skype GTalk   Вверх
ivg
Дата 19.12.2007, 12:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Autonomous R&D
**


Профиль
Группа: Участник
Сообщений: 686
Регистрация: 8.2.2006
Где: Екатеринбург

Репутация: 33
Всего: 81



Цитата(W0LF @  19.12.2007,  11:54 Найти цитируемый пост)
то, что в этом блоке
Код

synzhronized(a) {
}

называется критической секцией


В принципе это можно так назвать, только Thread.sleep() сам по себе ничего не лочит, и в отличии от wait() может быть вызван в любом месте программы, а не только в synzhronized блоке.
PM MAIL   Вверх
COVD
Дата 19.12.2007, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Цитата

А вот ещё вопрос: чем отличается notifyAll? Насколько я понимаю, если потоки стоят в режиме ожидания, то даже если их толкнуть все, то задвигается всё равно только один, ведь монитор может получить только один.


если несколько потоков стоят в wait(), то notifyAll их всех выведет из режима ожидания. И дальше они по-очереди будут выполнять код после wait(), как в обычном синхронизированном блоке. 
PM MAIL   Вверх
W0LF
Дата 19.12.2007, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


alexander lonsky
***


Профиль
Группа: Участник
Сообщений: 1164
Регистрация: 9.2.2006
Где: Ukraine.Dnepropet rovsk

Репутация: нет
Всего: 20



Цитата(ivg @  19.12.2007,  12:25 Найти цитируемый пост)
В принципе это можно так назвать, только Thread.sleep() сам по себе ничего не лочит, и в отличии от wait() может быть вызван в любом месте программы, а не только в synzhronized блоке. 

Ок, неправильно выразился - а Thread.sleep() приостанавливает текущий поток и при этом не отпускает текущую крит. секцию smile



--------------------
iOS developer
PM MAIL WWW Skype GTalk   Вверх
Dims
Дата 19.12.2007, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1016
Регистрация: 21.11.2006

Репутация: 4
Всего: 11



Цитата(COVD @  19.12.2007,  16:15 Найти цитируемый пост)
если несколько потоков стоят в wait(), то notifyAll их всех выведет из режима ожидания. И дальше они по-очереди будут выполнять код после wait(), как в обычном синхронизированном блоке. 

Но ведь они не могут по-очереди выполнять код! Они все претендуют на один и тот же монитор, следовательно, только кто-то один из них его получит. То есть, работать будет только один, до тех пор, пока он не освободит монитор.

Или, имеется в виду, что когда сделан одиночный notify, то в этом случае какой-то один из потоков проснётся, а остальные будут в режиме ожидания даже в том случае, если монитор будет свободен? То есть, они будут ждать сигнала notify даже при свободном мониторе.

Кажется, проясняется.

Получается, что фича, по которой в ответ на notify оживает один случайный поток, есть баг? 

Иными словами, если у меня такое в программе случилось, то, скорее всего, я ошибся. Я, скорее всего, должен был так запрограммировать, чтобы ждал у меня один конкретный поток, который я и имел в виду оживить по notify.
PM MAIL   Вверх
COVD
Дата 20.12.2007, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Цитата

То есть, они будут ждать сигнала notify даже при свободном мониторе.


По идее, так.

Цитата

Получается, что фича, по которой в ответ на notify оживает один случайный поток, есть баг?


Ну, это не совсем баг, потому что разработчики java вроде предупреждают в документации, что они не гарантируют того, что "первый заснул-первый проснулся".

Есть еще один "баг" под названием "spurious wakeup". т.е. поток самопроизвольно выходит из wait безо всякого notify. По этой причине wait принято ставить в цикл while, который в случае фальшивого пробуждения возвращает поток обратно в wait.  Это тоже описано в документации здесь :

Цитата

A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops, like this one: 

     synchronized (obj) {
         while (<condition does not hold>)
             obj.wait(timeout);
         ... // Perform action appropriate to condition
     }


Это сообщение отредактировал(а) COVD - 20.12.2007, 17:57
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0551 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.