Я интенсивно программирую на Java уже почти год. Я столкнулся с достаточно серьезной, на мой взгляд, проблемой, связанной с многопоточностью, которая, как мне кажется, неразрешима в рамках текущей реализации JVM от Oracle (вышесказанное относится к JDK 1.5 и выше).
Дело в том, что на данный момент в Java нет возможности безопасно остановить выполнение любого потока.
В этом посте объясняется, почему это так, и предлагается начать обсуждение способов решения этой проблемы.
Казалось бы, тривиальная задача: у нас есть некий Нить (поток), который, как мы знаем наверняка, безнадёжно застрял (может в цикле, может ещё что-то), при этом потребляя какие-то ресурсы.
Что нам с этим делать? Я хотел бы освободить наши ресурсы.
Что казалось бы проще? Ан нет, после детального изучения вопроса выяснилось, что у JVM просто нет инструкций по корректной остановке замороженного Thread. Старый метод Поток.
стоп() объявлен устаревшим и подвергнутым строгой анафеме.
Как указано в javadoc, этот метод «по своей сути небезопасен».
Ну, а если это небезопасно, то мы не будем этим пользоваться, дайте нам другой, безопасный метод. Но как ни странно, другого безопасного варианта не предлагается.
Он, безусловно, предлагает очень безопасные инструкции.
прерывание() .
Но, к сожалению, это безопасно, потому что абсолютно ничего не делает! Это всего лишь сообщение потоку: «Пожалуйста, остановитесь».
Но если поток проигнорировал это сообщение, то.
как сказано в документации: «Если поток не отвечает на Thread.interrupt(), вы можете использовать приемы, специфичные для вашего приложения».
Спасибо, что позволили мне.
Как говорится, крутись как хочешь.
Все становится еще сложнее, если задача выполняется в пуле потоков, например.
ExecutorService.submit(Работаемый) .
При этом мы даже не знаем, в каком потоке выполняется эта задача и уже не можем использовать даже запрещенный Thread.stop().
С другой стороны, у нас есть ссылка на Будущее , и у Future есть метод Future.cancel(логическое значение) , что должно отменить задачу.
Но если задача уже начала выполняться, вызов Future.cancel(true) фактически не остановит ее.
В глубине реализации Будущаязадача код выполняется: if (mayInterruptIfRunning) {
Thread r = runner;
if (r != null)
r.interrupt(); }
Те.
опять же, потоку, в котором выполняется задача, рекомендуется только прекратить выполнение.
Кроме того, у нас даже нет возможности узнать, выполняется задача в данный момент или нет. Кажется, есть метод Будущее.
isDone() , но опять же, кстати, он возвращает true не только после завершения выполнения задачи, но и сразу после вызова Future.cancel(), даже если задача еще выполняется (ведь Future.cancel(true) не останавливает задача, которая уже начала выполняться).
Хорошо, если мы напишем весь код сами, тогда мы сможем аккуратно его обработать в нужных местах.
Thread.isInterrupted() и все будет ОК.
Но что, если мы запустим сторонний код? Что, если у нас есть сервер, который можно расширить с помощью плагинов? Какой-нибудь криво написанный плагин запросто может вывести из строя весь сервер, потому что мы не можем корректно прервать выполнение зависшего плагина.
Признаюсь, я не знаю удовлетворительного решения.
Может быть, метод Thread.stop() не так уж и опасен? Очень хотелось бы услышать мнение Java-программистов и практиков по этому поводу.
Теги: #java #параллелизм #thread #будущее #многопоточность #java
-
Вам Нравится Пуля Рядом С Вашей Аватаркой?
19 Oct, 24 -
Moose: Ооп В Perl
19 Oct, 24 -
Софтфон – Офисный Телефон В Твоем Смартфоне
19 Oct, 24 -
Emi Отвергает Слияние Warner
19 Oct, 24 -
Какие К Черту Социальные Сети?
19 Oct, 24 -
Выпущен Mps 2017.3
19 Oct, 24