![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| Platon |
|
||||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Здравствуйте, уважаемые.
У меня тут щепетильная ситуация... Сначала искал возможности для асинхронной работы с удаленными компами, нашел, а теперь не могу сделать синхронную работу...
ответные сообщения идут от соединений вот так:
Думал сделать так:
Все бы ничего но для каждого синхронизированного запроса так изголяться?! уж тяжело даже мне. Благо пока 1 такой метод, но если поставить на массовый поток клепание синхронизированых методов? Я явно упустил какой-то легкий подход. Это сообщение отредактировал(а) Platon - 23.1.2008, 12:03 |
||||||||
|
|||||||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Кстати вот мой объект, ожидающий ответа:
Но, боюсь, что если более 1 запроса будет ожидать обработки, то могут возникнуть разного рода проблемы? К примеру, в сокет отправилось 2 запроса о проверке наличия пользователя, и как я вижу, 2 потока лягут спать на объекте ResponseWaitor и при обращении к методу ResponseWaitor.notify() неизвестно какой поток пробудится... |
|||
|
||||
| LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Я делал так:
- один поток обрабатывал сеть (отправлял и получал оттуда данные) - другие потоки вызывали методы этого объекта для отправки данных - когда метод хотел синхронно отправить сообщение, объект работающий с потоком обработки сети отправлял данные, записывал в что ожидается ответ на сообщение с таким-то ID, и усыплял поток - когда приходило сообщение, проверял что это подтверждение, будил все потоки и у каждого проверял, что это сообщение для него, нужный поток получал управление обратно и ответ, а все остальные снова засыпали дальше -------------------- 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. |
|||
|
||||
| AntonSaburov |
|
|||
![]() Штурман ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 5658 Регистрация: 2.7.2002 Где: Санкт-Петербург Репутация: 51 Всего: 118 |
Что-то ты и правда намудрил. Попробуй описать задачу целиком - может найдется просто иное решение. Проще и "стандартнее".
|
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
LSD, ну на самом деле не намного проще получается :( или я просто не понял.
AntonSaburov, использую библиотеку Apache MINA для организации сети. Задача: оформить синхронизированную работу функций. Вот я накидал как оно выглядит Клиентская часть Серверная часть Главная загвоздка находится в классе ServerConnection, как раз там необходимо усыплять потоки. |
|||
|
||||
| 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. |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Хм, странно, попробовал потестировать со своим ResponseWaitor'ом тест прошел, глюков и дедлоков не было... надо думать что всё таки так дело нормально пройдет, проверим еще на нескольких тачках.
|
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
Очевидно, вы хотите синхронные запросы пропускать через один канал связи, т.е. через один сокет. Это неестественно. Натурально будет, если для синхронного запроса открыть новое соединение, получить ответ и закрыть соединение. Используя асинхронный канал для синхронных запросов вы получаете свои трудности: - иметь коллекцию, где потоки запросов будут ожидать ответа, - иметь таймер, который мониторит коллекцию и выбрасывает потоки, у которых задержка ответа превышает таймаут, - в каждом запросе отправлять уникальный ID запроса - в каждом ответе на запрос возвращать ID запроса, чтобы отыскать поток в коллекции и разбудить его. |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
||||
|
||||
| LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Ты главное потоков побольше запусти, и дольше тестируй.
P.S. У меня там ещё тайм аут обрабатывался. А у тебя как с этим? -------------------- 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. |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
На самом деле никак. Я еще вечерком подумаю над тем что мне насоветовали ^_^
|
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
именно так, потому что не надо синхронную схему приспосабливать к асинхронному каналу связи - никаких ID, коллекций, таймеров и блоков синхронизаций. |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
COVD, это уже получается сервис? но это соединение также обслуживает асинхронные запросы.
В моем примере на самом деле проблема только с тем кто разбудится. Но 100% Гарантировано, что при записи в поток запросов ответы придут в той же (ненарушенной) последовательности. |
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
фактически, да. Если сиюминутная проблема только в том, "кто разбудится", то кладите потоки (т.е. обьекты, на которых они спят) в ArrayList и в том же порядке извлекайте и будите. Это сообщение отредактировал(а) COVD - 23.1.2008, 18:56 |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Ок, логичное решение... не догадался.
НО, вот будет утомительно плясать вокруг каждого такого метода... Каков же опыт RMI, на сколько я знаю там все методы сделаны в синхронном стиле. но нам плясать никак не надо. Может быть этот опыт можно повзаимствовать или придется все методы делать синхронными. |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Свелось всё к классической задачке ^_^
Это сообщение отредактировал(а) Platon - 24.1.2008, 11:40 |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
И получается не так уж и страшно:
|
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Нет, вариант оказался неправильным, вот новый, но я даже не рискнул его запустить, просто не укладывается в мозгу как сделать правильно.
Опытные тредеры!!! Нужна консультация.
Добавлено через 6 минут и 47 секунд Хм, нет, этот вариант конечно же завален. |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Вот кажется валидный пример:
|
|||
|
||||
| Prol |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 11.1.2008 Где: Кыев, Украина Репутация: нет Всего: нет |
Усыплять поток - это всё равно что хальтовать процессор в ожидании немаскируемого прерывания :о))) Моветон :о) Да посади проц в фарева цикл на обработку задач :о) |
|||
|
||||
| ivg |
|
|||
![]() Autonomous R&D ![]() ![]() Профиль Группа: Участник Сообщений: 686 Регистрация: 8.2.2006 Где: Екатеринбург Репутация: 33 Всего: 81 |
||||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Prol, от куда такие сведения? лупить в бесконечном цикле обработку задачи, которые поступают через неопределенные промежутки времени. Это убийство процессорного времени воистину!
|
|||
|
||||
| Prol |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 11.1.2008 Где: Кыев, Украина Репутация: нет Всего: нет |
Процессор должен работать, а человек - думать :о) Не слипайте потоки, дайте им работу :о) Если вы слипаете поток, значит он не нужен в вашей проге :о) Зачем заводить поток, который вы же сами и останавливаете? Вот классно сделано в транспьютерах: есть очередь процессоров, есть очередь задач, свободный процессор отдаётся ожидающей задаче :о) Если процессорам нечего делать, значит все задачи выполнены :о) |
|||
|
||||
| LSD |
|
||||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Полная чушь! 1. Приостанавливать поток, и выполнять halt у процессора - это две большие разницы. 2. Если задача предполагает ожидание некого события, то поток должен заснуть, а не молотить никому не нужный цикл напрасно загружая процессор. Добавлено через 46 секунд
Ты не понимаешь разницы между остановкой и приостановкой? -------------------- 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. |
||||
|
|||||
| Prol |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 11.1.2008 Где: Кыев, Украина Репутация: нет Всего: нет |
А какое отношение поток имеет к задаче? Это два разных объекта :о) Если задаче нужно чего-то ожидать, то причём тут поток? Поток передаётся другой задаче :о) |
|||
|
||||
| LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Тяжкое наследие DOS-а, сами распределяем память, сами организуем многозадачность Во первых попробуй реализовать такой механизм, и посмотрим что у тебя получится Во вторых, что ты будешь делать если нужные данные поступили и пора возвращать управление первой задаче, а вторая задача которая заняла поток, еще и не думает заверщаться, или хуже того блокирована на IO-операции? -------------------- 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. |
|||
|
||||
| Prol |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 11.1.2008 Где: Кыев, Украина Репутация: нет Всего: нет |
Нет необходимости писать свое Даг Ли создал отличную открытую библиотеку утилит параллельности, util.concurrent, которая включает объекты-мьютексы, семафоры, коллекции, такие как очереди и хэш-таблицы, хорошо работающие при параллельном доступе, и несколько реализаций рабочей очереди. Класс PooledExecutor из этого пакета - эффективная, широко использующаяся, правильная реализация пула потоков, основанного на рабочей очереди. Прежде чем пытаться писать собственное программное обеспечение, которое вполне может оказаться неправильным, вы можете рассмотреть использование некоторых утилит в util.concurrent. Библиотека util.concurrent включена в Java Development Kit 1.5. Вот хороший учебник для овладения с практическими примерами. http://gee.cs.oswego.edu/dl/classes/EDU/os...rent/intro.html Это сообщение отредактировал(а) Prol - 27.1.2008, 16:49 |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
В этом вопросе я уже не компетентен...
Добавлено через 9 минут и 33 секунды хммм, в тамом случае, хотелось бы увидеть от Prol решения моей проблемы с помощью стандартного пакета Java, из этого я думаю, сможет получиться хорошая статья. Это сообщение отредактировал(а) Platon - 27.1.2008, 17:25 |
|||
|
||||
| LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Из java.util.concurrent в данном случае, я вижу применимость только для Lock/Condition. Каким образом ты предлагаешь использовать PooledExecutor для данной задачи? -------------------- 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. |
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
Не морочьте голову
Prol, java потоки - это воплощение вашей идеи с независимыми приложениями, использующими общую память. Можете гордиться Это сообщение отредактировал(а) COVD - 28.1.2008, 19:32 |
|||
|
||||
| Prol |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 11.1.2008 Где: Кыев, Украина Репутация: нет Всего: нет |
К сожалению все они рухнут, если произойдёт operation exeption, access violation или overflow в самой JVM. |
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
Ничто не вечно.
|
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Dear Lord, help me!!!
Я до сих пор не могу найти решения. Мое последнее решение также впадает в ступор:
Добавлено @ 19:11 Я не уверен как правильно называется класс Flag, возможно это некий семафор. Это сообщение отредактировал(а) Platon - 20.2.2008, 13:12 |
|||
|
||||
| SoulKeeper |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 375 Регистрация: 14.1.2007 Где: Ukraine, Lviv. Репутация: 11 Всего: 15 |
Я конечно понимаю что изобретение своего велосипеда делает программиста более квалифицированым, но есть
1). RMI. Правда кажись работает на блокирующем I/O, в дебри не влезаю, да и для моих потребностей, обслуживание от силы 15 клиентов, мне nio не особо и нужно. 2). JERI в Jini. В свое время обращал внимание, но в глубь копать не стал, т.к. вариант #1 подошел вполне. Кажись есть возможность использование nio. Собственно вот такие вот дела |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Зачем мне ваши технологии, когда я могу без них обойтись. Я с удовольствием перейму стандартное решение текущей задачи, но технологии мне советовать не надо.
|
|||
|
||||
| SoulKeeper |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 375 Регистрация: 14.1.2007 Где: Ukraine, Lviv. Репутация: 11 Всего: 15 |
Вообще-то это и есть стандартные решения текущей задачи.
Это сообщение отредактировал(а) SoulKeeper - 20.2.2008, 11:07 |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
задача сводится лишь к тому чтобы из асинхронной работы была возможность запросить и дождаться ответа от общего объекта, причем в пределах одной JVM. Спрашивается зачем мне RMI???
Это сообщение отредактировал(а) Platon - 20.2.2008, 11:30 |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Последнее из выведенного на экран оказывается всегда похожим на
Всегда заканчивается ожиданием готовности флажка. и почему то в этот момент он не срабатывает :( хотя во 2-й строчке он уже был выброшен. |
|||
|
||||
| Platon |
|
||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Вот оно!!! Как говорится: "Эврика"!!!
Жаль, что мне никто не помог, и столько времени пришлось ломать голову над этим пустячком. Проблема оказалась вот в этом куске:
Поменял на
Добавлено через 10 минут Я бы сам себе за такие мучения орден вручил бы! Это сообщение отредактировал(а) Platon - 22.2.2008, 13:28 |
||||||
|
|||||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
Очень удобен для таких задач класс java.util.concurrent.LinkedBlockingQueue - никаких wait и synchronized не нужно. Единственное неудобство - эта очередь не принимает на входе null. Поэтому конец очереди , если есть в нем необходимость, можно определить только поставив в очередь специальный обьект и ловить его на выходе через instanceof .
|
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
COVD, дорогой, где ж вы неделю назад были???!!!
|
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
Я просто не сразу понял, с чем вы сражались.
Еще мне кажется, вы не предусмотрели таймаут на ожидание ответа. Ответ ведь может никогда и не придти. А в LinkedBlockingQueue его можно поставить и тогда, если время ожидания ответа превысит таймаут, очередь выбросит null (поэтому null и запрещен на входе). Это сообщение отредактировал(а) COVD - 22.2.2008, 17:50 |
|||
|
||||
| Platon |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Смотрим сюда.
Теперь смотрим на конец вывода в консоль:
проблемка возникла... судя по всему, в некоторые некоторые моменты poll() выдают одинаковый результат 2-м потокам. |
||||
|
|||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
у меня ваш код нормально сработал - последнее выведенное число 39999. А надпись "There are .." выскакивает где-то в середине вывода на консоль, т.е. это еще не конец работы программы.
Это сообщение отредактировал(а) COVD - 22.2.2008, 18:36 |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
не-не, надо несколько раз прогу запустить + если где-то в середине, увеличьте задержку до 10 секунд.
|
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
зачем вообще эта задержка? поток, который кладет данные в очередь, может закончить свою работу в любое время. независимо от читающих
|
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Ок, код некомпетентный, вот новый:
Добавлено через 2 минуты и 50 секунд Если что, сразу скажу, пробовал add/get делать синхронизированными. |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Вот и подошла к концу моя эпопея. Спасибо COVD за отличную подсказку, работа моего примера была неправильной из-за метода poll() который не ждет появления объекта в очереди, а сразу выбрасывает null.
Правильным решением здесь будет take() Он точно ждет. |
|||
|
||||
![]()
|
| Правила форума "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. |