![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| sergakrem |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 38 Регистрация: 28.7.2006 Где: Украина, г. Киев Репутация: нет Всего: нет |
Всем, доброе время суток.
Подскажите пожалуйста ответ на следующий вопрос: Есть некоторый класс, один из методов которого выполняет достаточно ресурсоемкую и длительную опреацию (вызвая толпу других методов и т.д.). Нужно следить за статусом выполнения этого метода на веб-странице. Для этого создана сама страница и сервлет, который будет заниматься опросом. Но так же стоит задача управлением выполнения этого кода (реализовывающего метод), я имею ввиду - старт, пауза, resume и стоп. Т.е. необходимо, выполнить данный код в потоке, который можно запустить, остановить, и т.д. Сам код (содержимое метода) был написан таким образом, что его достаточно сложно модифицировать для грамотной реализации управления состояниями, т.е. хотелось бы просто выполнять его в потоке в том виде, в котором он есть. Я решал это приблизительно таким образом:
(Здесь все, что находится внутри public void run() { ... } собственно и есть само тело метода) У Thread методы suspend(), stop() и resume() объявленны, как Deprecated - соответственно, не хотелось бы ими пользоваться, хотя они по-видимому решили бы задачу. Собственно, вопрос заключается в том: есть ли у кого какие идеи решения такой задачи каким-нибудь более корректным способом, нежели использования Deprecated методами. Заранее, большое спасибо. Это сообщение отредактировал(а) sergakrem - 29.8.2006, 17:25 |
|||
|
||||
| Stampede |
|
|||
![]() Гносеолог ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 963 Регистрация: 25.4.2005 Где: Calgary, Alberta, Canada Репутация: 66 Всего: 144 |
Увы, единственный безопасный способ управлять состоянием процедуры, выполняющейся в отдельном потоке (приостановить, продолжить, завершить) - это выставлять ей извне всякие разные флажки.
Что касается реагирования на флажки, то тут придется выделять фрагменты кода, представляющие более или менее законченную операцию, и по окончании каждой из них проверять значение флага и соостветственно предпринимать какие-то действия. Хорошо, если какая-то продолжительная операция выполняется в циклле - тогда проверку флага можно вставить внутрь тела цикла. Тут может возникнуть вопрос: а зачем, собственно, весь этот геморрой? Чем были плохи ныне упраздненные методы pause(), resume() и stop()? Плохи они тем, что позволяют любому внешнему процессу весьма авторитарным образом (например, по инициативе юзера) вмешиваться в ход выполнения процедуры, будучи при этом абсолютно ни уха ни рыла в том, что именно в нем происходит. А происходить может все что угодно, в том числе достаточно деликатные операции, которые блокируют всякие другие ресурсы. Так вот, посольку только сам поток знает, когда он может безопасно приостановиться/завершиться, и какие действия при этом следует выполнить, чтобы не подвесить всю систему, то ему, как говорится, и все карты в руки. А мы, как сущности достаточно посторонние, можем только в мягкой форме выразить пожелание об изменении его состояния. Таким образом, на смену авторитарному стилю управления потоками пришел более мягкий, демократический. Я бы назвал его методом делегирования полномочий. В этом, по-видимому, нашел отражение тот факт, что менеджеры среднего звена в IT-индустрии таки действительно очень мало смыслят в технологических тонкостях создаваемых продуктов, и если командный стиль годится в армии или там где-нибудь на буровой, то в таком тонком деле как создание ПО на девелоперов лучше все-таки не давить, а предоставить им относительную свободу реализации -------------------- "If you want something done right, do it yourself" По секрету: выучить английский - реально! |
|||
|
||||
| sergakrem |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 38 Регистрация: 28.7.2006 Где: Украина, г. Киев Репутация: нет Всего: нет |
Ok. Спасибо за ответ.
Хочу тогда посоветоваться по этому поводу
Т.е. я правильно понимаю - если я (как разработчик) знаю, что в моем коде (в данном случае в этом методе, который я хотел бы выполнять в потоке) не происходит никаких блокировок и других "деликатных" Хотя я вобщем-то подумал еще об одном способе - блокировать синхронизированный объект (если мне надо остановить выполнение кода), который повсеместно там используется в коде, и соответственно - отпускать его (если я хочу продолжить выполнение). Ну а остановка выполнения (функция stop) - просто прибивать ссылку на объект потока (хотя на сколько я помню - это не поможет), ну или какой-нибудь другой способ. Это сообщение отредактировал(а) sergakrem - 31.8.2006, 19:11 |
|||
|
||||
| Stampede |
|
||||
![]() Гносеолог ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 963 Регистрация: 25.4.2005 Где: Calgary, Alberta, Canada Репутация: 66 Всего: 144 |
Я понимаю, что ты хочешь победить это дело, так сказать, малой кровью. Но я хочу предупредить, что синхронизация потоков - дело и без того достаточно тонкое, а если этим механизмом начать пользоваться для реализации вещей, для которых он в общем-то не предназначался, то может запросто получиться, что ты, сам того не подозревая, подложишь себе мину замедленного действия. Что я имею в виду? Ну прежде всего то, что логику, использующую блокировки, очень непросто писать и еще труднее отлаживать. Как минимум нужно очень хорошо представлять себе, как работают мониторы объектов и все, что с ними связано (например, поведение при повторном вхождении в синхронизированный участок кода). Так вот, даже если ты запрограммируешь все это дело и оно вроде как заработает, не факт что под нагрузкой не начнут вылазить всякие разные странности. Потому что, повторяю, смоделировать все возможные сценарии переходов состояний на этапе тестирования - задача в общем случае очень нетривиальная. Поэтому если сравнивать варианты, я бы наверное лучше тупо в лоб задействовал "устаренные" методы - если, как ты говоришь, ты уверен, что ничего страшного при этом не произойдет. Хотя, конечно, трудно советовать что-то конкретное, не зная подробностей. Что хоть за задача-то? Если не военная тайна, конечно
Дак именно что не поможет! Если извне ничего не делать, то поток будет мослать до тех пор пока не дойдет до конца метода run(). Коль скоро ты не хочешь влезать внутрь готового кода, можно опять же насильно вызвать stop(), но в этом случае по крайней мере нужно оформить действия по освобождению ресурсов в виде конструкции try-finally:
Ди, и вот еще что я подумал. Какие-то смутные подозрение вызывает твое упоминание о том, что код процедуры содержит кучу синчронизованных участков. С чего бы это они там были? Ты точно уверен, что ничего не подвесишь прямыми вызовами suspend()? -------------------- "If you want something done right, do it yourself" По секрету: выучить английский - реально! |
||||
|
|||||
| sergakrem |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 38 Регистрация: 28.7.2006 Где: Украина, г. Киев Репутация: нет Всего: нет |
Да задача-то конечно - не военная тайна.
Просто она вряд ли будет сама по себе интересна. Эта веб-прога просто является фронт-эндом к одной системе, к которой у меня есть интерфейс через JNI. Идея такая - есть объект (методы которого я хочу выполнять в потоке), который просто дергает за native функции, получает оттуда некоторые данные, приводит их в нужный вид а затем передает их на формирование вида в JSP. Один из его методов о-о-о-о-чень долго может выполняться, и собственно пользователю нет нужды ждать, пока он отработает - пользователь сможет на результаты потом посмотреть. Просто дело в том, что перед выполнением этого метода объект некоторое время действиями пользователя на странице инициализируется начальными данными, а только затем уже, их используя, обрабатывает результаты native функций, которые он потом дергает. Я вот, собственно, о чем и подумал - я же могу для каждого такого выполнения создавать один такой объект, который никак не связан с себе подобными - и выполнять его "длинный" метод в бэкграунде, а пользователю в это время давать возможность уже создавать и настраивать (инициализировать) следующий объект, для следующего исполнения. |
|||
|
||||
| COVD2 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 28 Регистрация: 10.6.2006 Репутация: нет Всего: 1 |
Наверное, дело в том, что сам поток как раз и не знает. Если бы знал, то при поступлении команды, скажем, stop(), он бы мог продолжить выполнение до ближайшей безопасной точки и остановиться (или откатиться назад и снять, например, поставленную им блокировку Это сообщение отредактировал(а) COVD2 - 2.9.2006, 18:36 |
|||
|
||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |