![]() |
Модераторы: LSD, AntonSaburov |
![]() ![]() ![]() |
|
lavan |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 101 Регистрация: 21.4.2011 Репутация: нет Всего: нет |
Столкнулся с непонятной проблемой.Хочу решить задачу типа два потока заполняют буфер по очереди.
Сначала поток А выводит символ "А" затем поток Б символ "Б".Ловлю дедлок,при первом же проходе по циклу. Вставил пару предложений для проверки,получается что компилятор(netbeans) оптимизирует volatile переменную? Суть алгоритма такова:Если поток А находится в синхронизирующем блоке А то поток Б засыпает. Если поток А заходит в синхр блок то он будит поток Б.На выходе получаю [A] A osv B A wait -1 B wait -0 Получается поток А первый проходит все мониторы,а поток Б ждет освобожд монитора Б.Поток А меняет флаги в мониторе Б давая тем самым потоку Б отработать выходит из монитора Б.Поток Б наконец то попадает в монитор Б сейчас уже флагБ==ложь и поток Б не должен уснуть по wait! Но он засыпает и получается дедлок. Все переменные типа volatile.Такое может происходить,если два потока находились в одном мониторе одновременно что по идее не возможно!или компилятор берет старое значения флага!Вопрос,что не так?Где я ошибся?? Да,и еще компилятор выдает предупреждение "синхронизация по не полному полю" что это значит?
|
|||
|
||||
LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
У объекта Boolean есть два константы TRUE и FALSE и если использовать автовайринг, то будут создавать не новые объекты а использоваться эти две константы. Так что snA, snB, fl, fll инициализируются одним и тем же объектом.
Создай отдельные объекты на которых и синхронизируйся. -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
Pawl |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 649 Регистрация: 22.4.2008 Где: Витебск Репутация: 7 Всего: 28 |
Проблем в том, что тут у Вас получаются 2 разных объекта, каждый со своим набором полей, когда Вы пишете
Тогда получится, что оба потока меняют значение переменных одного объекта, и будет Вам счастье:) -------------------- В действительности всё совсем не так, как на самом деле |
||||
|
|||||
lavan |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 101 Регистрация: 21.4.2011 Репутация: нет Всего: нет |
а разве синхронизация не должна происходить на одном и том же объкте синхронизации?
|
|||
|
||||
Pawl |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 649 Регистрация: 22.4.2008 Где: Витебск Репутация: 7 Всего: 28 |
Ну да, первый поток захватывает монитор объекта, методом wait отправляет другой поток покурить, а сам в это время что-то с этим объектом делает. Затем зовет второй поток методом notify и сам уходит курить. и с этим же объектом работает уже другой поток. А у Вас получается следующее:
первый поток работает с объектом класса A
второй поток работает с объектом класса В. Эти потоки не пересекаются друг с другом, поскольку работают каждый на своем объекте. Поэтому синхронизация у Вас тут как раз на разных объектах. -------------------- В действительности всё совсем не так, как на самом деле |
||||||
|
|||||||
lavan |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 101 Регистрация: 21.4.2011 Репутация: нет Всего: нет |
Не понял,я создаю объект класса Boolean,передаю его по ссылке и делаю volatile.Вроде он должен изменяться? |
||||
|
|||||
LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
А дедлок откуда? -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
Pawl |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 649 Регистрация: 22.4.2008 Где: Витебск Репутация: 7 Всего: 28 |
Ну, получается, что нет. я тут даже набросал следующий код:
так вот, после вызова setA на объекте а, поле aB все-равно осталось true. Добавлено @ 15:58 Ну как же, сначала первый поток отправляется курить на объекте класса А:
а затем - второй также отправляется курить на объекте класса В:
Это сообщение отредактировал(а) Pawl - 6.7.2012, 15:59 -------------------- В действительности всё совсем не так, как на самом деле |
||||||
|
|||||||
lavan |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 101 Регистрация: 21.4.2011 Репутация: нет Всего: нет |
Ну хорошо,если каждый поток имеет свой объект синхр,то почему иногда они все таки отрабатывают правильно?
|
|||
|
||||
Pawl |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 649 Регистрация: 22.4.2008 Где: Витебск Репутация: 7 Всего: 28 |
???! Во как! Тогда не знаю, надо подумать... -------------------- В действительности всё совсем не так, как на самом деле |
|||
|
||||
jk1 |
|
||||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 1168 Регистрация: 17.10.2008 Где: Санкт-Петербург Репутация: 40 Всего: 75 |
Прогнал у себя, действительно 1-2 запуска из 10 завершаются успешно. Race condition как он есть. Потом заменил
на
для обоих потоков, как и положено при работе с wait(). После этого за пару тысяч запусков ни один успешно не отработал. Из всего этого следует вывод, что дело в вероятности потока самопроизвольно просыпаться из wait(). Если он действительно проснулся сам по себе без notify(), то программа завершается. Если нет, то стоит залоченная. P.S.: Синхронизация тут все-таки на одинаковых объектах, snA и snB внутри потоков не присваиваются, а вот флаги расходятся кто куда P.P.S: Интересный эффект получается при использовании вот такой комбинации начальных данных
теперь уже большинство запусков успешны, а отдельные - падают -------------------- Opinions are like assholes — everybody has one |
||||||||
|
|||||||||
Pawl |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 649 Регистрация: 22.4.2008 Где: Витебск Репутация: 7 Всего: 28 |
Извините, не могли бы Вы обосновать, почему на одинаковых? Ведь snA и snB имеются как у объекта класса А, так и у В, и изменение значения того же snA на одном объекте никак не затронет значение snA на другом? -------------------- В действительности всё совсем не так, как на самом деле |
|||
|
||||
jk1 |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 1168 Регистрация: 17.10.2008 Где: Санкт-Петербург Репутация: 40 Всего: 75 |
Потому что внутри классов A и B не выполняется присвоения snA и snB, на которых происходит синхронизация, кроме как в конструкторе. А в конструктор передали одну и ту же пару объектов. Присваиваются только флаги, на которых синхронизация не делается. -------------------- Opinions are like assholes — everybody has one |
|||
|
||||
Pawl |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 649 Регистрация: 22.4.2008 Где: Витебск Репутация: 7 Всего: 28 |
То есть, Вы хотите сказать, что в объектах классов А и В изменяются не локальные копии полей, а именно те объекты Boolean, которые передались в конструктор? Это сообщение отредактировал(а) Pawl - 7.7.2012, 00:19 -------------------- В действительности всё совсем не так, как на самом деле |
|||
|
||||
jk1 |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 1168 Регистрация: 17.10.2008 Где: Санкт-Петербург Репутация: 40 Всего: 75 |
Нет, я хочу сказать, что snA и snB там не изменяются. Вообще. Их можно final сделать. Перечитайте пожалуйста внимательно код из первого поста. -------------------- Opinions are like assholes — everybody has one |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Java" | |
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |