| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java EE (J2EE) и Spring > Выполнение методов класса в отдельном потоке |
| Автор: sergakrem 29.8.2006, 17:24 | ||
| Всем, доброе время суток. Подскажите пожалуйста ответ на следующий вопрос: Есть некоторый класс, один из методов которого выполняет достаточно ресурсоемкую и длительную опреацию (вызвая толпу других методов и т.д.). Нужно следить за статусом выполнения этого метода на веб-странице. Для этого создана сама страница и сервлет, который будет заниматься опросом. Но так же стоит задача управлением выполнения этого кода (реализовывающего метод), я имею ввиду - старт, пауза, resume и стоп. Т.е. необходимо, выполнить данный код в потоке, который можно запустить, остановить, и т.д. Сам код (содержимое метода) был написан таким образом, что его достаточно сложно модифицировать для грамотной реализации управления состояниями, т.е. хотелось бы просто выполнять его в потоке в том виде, в котором он есть. Я решал это приблизительно таким образом:
(Здесь все, что находится внутри public void run() { ... } собственно и есть само тело метода) У Thread методы suspend(), stop() и resume() объявленны, как Deprecated - соответственно, не хотелось бы ими пользоваться, хотя они по-видимому решили бы задачу. Собственно, вопрос заключается в том: есть ли у кого какие идеи решения такой задачи каким-нибудь более корректным способом, нежели использования Deprecated методами. Заранее, большое спасибо. |
| Автор: Stampede 29.8.2006, 19:29 | ||
Увы, единственный безопасный способ управлять состоянием процедуры, выполняющейся в отдельном потоке (приостановить, продолжить, завершить) - это выставлять ей извне всякие разные флажки.
Что касается реагирования на флажки, то тут придется выделять фрагменты кода, представляющие более или менее законченную операцию, и по окончании каждой из них проверять значение флага и соостветственно предпринимать какие-то действия. Хорошо, если какая-то продолжительная операция выполняется в циклле - тогда проверку флага можно вставить внутрь тела цикла. Тут может возникнуть вопрос: а зачем, собственно, весь этот геморрой? Чем были плохи ныне упраздненные методы pause(), resume() и stop()? Плохи они тем, что позволяют любому внешнему процессу весьма авторитарным образом (например, по инициативе юзера) вмешиваться в ход выполнения процедуры, будучи при этом абсолютно ни уха ни рыла в том, что именно в нем происходит. А происходить может все что угодно, в том числе достаточно деликатные операции, которые блокируют всякие другие ресурсы. Так вот, посольку только сам поток знает, когда он может безопасно приостановиться/завершиться, и какие действия при этом следует выполнить, чтобы не подвесить всю систему, то ему, как говорится, и все карты в руки. А мы, как сущности достаточно посторонние, можем только в мягкой форме выразить пожелание об изменении его состояния. Таким образом, на смену авторитарному стилю управления потоками пришел более мягкий, демократический. Я бы назвал его методом делегирования полномочий. В этом, по-видимому, нашел отражение тот факт, что менеджеры среднего звена в IT-индустрии таки действительно очень мало смыслят в технологических тонкостях создаваемых продуктов, и если командный стиль годится в армии или там где-нибудь на буровой, то в таком тонком деле как создание ПО на девелоперов лучше все-таки не давить, а предоставить им относительную свободу реализации |
| Автор: sergakrem 31.8.2006, 19:09 | ||
| Ok. Спасибо за ответ. Хочу тогда посоветоваться по этому поводу
Т.е. я правильно понимаю - если я (как разработчик) знаю, что в моем коде (в данном случае в этом методе, который я хотел бы выполнять в потоке) не происходит никаких блокировок и других "деликатных" Хотя я вобщем-то подумал еще об одном способе - блокировать синхронизированный объект (если мне надо остановить выполнение кода), который повсеместно там используется в коде, и соответственно - отпускать его (если я хочу продолжить выполнение). Ну а остановка выполнения (функция stop) - просто прибивать ссылку на объект потока (хотя на сколько я помню - это не поможет), ну или какой-нибудь другой способ. |
| Автор: sergakrem 31.8.2006, 21:09 |
| Да задача-то конечно - не военная тайна. Просто она вряд ли будет сама по себе интересна. Эта веб-прога просто является фронт-эндом к одной системе, к которой у меня есть интерфейс через JNI. Идея такая - есть объект (методы которого я хочу выполнять в потоке), который просто дергает за native функции, получает оттуда некоторые данные, приводит их в нужный вид а затем передает их на формирование вида в JSP. Один из его методов о-о-о-о-чень долго может выполняться, и собственно пользователю нет нужды ждать, пока он отработает - пользователь сможет на результаты потом посмотреть. Просто дело в том, что перед выполнением этого метода объект некоторое время действиями пользователя на странице инициализируется начальными данными, а только затем уже, их используя, обрабатывает результаты native функций, которые он потом дергает. Я вот, собственно, о чем и подумал - я же могу для каждого такого выполнения создавать один такой объект, который никак не связан с себе подобными - и выполнять его "длинный" метод в бэкграунде, а пользователю в это время давать возможность уже создавать и настраивать (инициализировать) следующий объект, для следующего исполнения. |
| Автор: COVD2 2.9.2006, 18:14 | ||
Наверное, дело в том, что сам поток как раз и не знает. Если бы знал, то при поступлении команды, скажем, stop(), он бы мог продолжить выполнение до ближайшей безопасной точки и остановиться (или откатиться назад и снять, например, поставленную им блокировку |