Thread.stop и друзья когда-либо безопасны в Java?

stop(), suspend(), и resume() в java.lang.Thread удерживаются от использования, потому что они небезопасны. Oracle рекомендовала, чтобы работа вокруг использовала Thread.interrupt(), но тот подход не работает во всех случаях. Например, если Вы - вызов метод библиотеки, который явно или неявно не проверяет interrupted флаг, у Вас нет выбора, кроме как ожидать вызова для окончания.

Так, я задаюсь вопросом, возможно ли охарактеризовать ситуации, где (доказуемо) безопасно звонить stop() на Потоке. Например, был бы это быть безопасным к stop() поток, который действительно только звонил find(...) или match(...) на a java.util.regex.Matcher?

(Если бы существуют какие-либо инженеры Oracle, читающие это... категорический ответ действительно ценился бы.)

Править: Ответы, которые просто вновь заявляют о молитве, которую Вы не должны называть stop() потому что это удерживается от использования, небезопасно, независимо от того, что упускает суть этого вопроса. Я знаю, что это, это по-настоящему небезопасно в большинстве случаев, и что, если существует жизнеспособная альтернатива, необходимо всегда использовать это вместо этого.

Этот вопрос о случаях подмножества, где это безопасно. А именно, каково то подмножество?

43
задан Stephen C 10 November 2019 в 00:19
поделиться

5 ответов

Здесь ' )

Первое условие означает, что остановленный поток не оставит никаких внешних структур данных или ресурсов в несогласованном состоянии. Сюда входят структуры данных, к которым он может получать доступ (читать) в мьютексе. Второе условие означает, что останавливаемый поток не может оставить в ожидании какой-либо другой поток. Но он также запрещает использование любого механизма синхронизации, кроме мьютексов простых объектов.

Останавливаемый поток должен иметь способ доставить результаты каждого вычисления в управляющий поток. Эти результаты создаются / изменяются останавливаемым потоком, поэтому нам просто нужно убедиться, что они не видны после остановки потока. Например, результаты могут быть назначены частным членам объекта Thread и «защищены» с помощью флага, который атомарно потоком сообщает, что он «готов».

EDIT : Эти условия довольно жесткие. Например, для безопасной остановки потока «оценщика регулярных выражений», если мы должны гарантировать, что механизм регулярных выражений не изменяет какое-либо внешне видимое состояние. Проблема в том, что это может случиться, в зависимости от того, как вы реализуете поток!

  1. Методы Pattern.compile (...) могут обновлять статический кеш скомпилированных шаблоны, и если бы они это сделали, они бы (должны были) использовать для этого мьютекс. (На самом деле, версия OpenJDK 6.0 не кэширует шаблоны, но Sun, вероятно, может это изменить.)
  2. Если вы попытаетесь избежать 1) компиляции регулярного выражения в потоке управления и предоставления предварительно созданного экземпляра Matcher , то поток регулярных выражений действительно изменяет внешне видимое состояние.

В первом случае у нас, вероятно, будут проблемы. Например, предположим, что HashMap использовался для реализации кэша и что поток был прерван во время реорганизации HashMap.

Во втором случае все будет в порядке при условии , что Сопоставитель не был передан другому потоку, и предоставил , что поток контроллера не сделал этого. Я пытаюсь использовать Matcher после остановки потока сопоставления регулярных выражений.

Так что же нам остается?

Думаю, я определил условия, при которых теоретически безопасно останавливать потоки. Я также думаю, что теоретически возможно статически анализировать код потока (и методы, которые он вызывает), чтобы увидеть, всегда ли будут выполняться эти условия. Но я не уверен, действительно ли это практично.

Есть ли в этом смысл? Я что-то пропустил?

РЕДАКТИРОВАТЬ 2

Все становится немного сложнее, если учесть, что код, который мы, возможно, пытаемся уничтожить, может быть ненадежным:

  1. Мы не можем полагаться на «обещания»; например, аннотации к ненадежному коду о том, что он либо убиваемый, либо не убиваемый.

  2. На самом деле нам нужно иметь возможность помешать ненадежному коду выполнять действия, которые сделали бы его неубиваемым ... согласно выявленным критериям.

Я подозреваю, что это повлечет за собой изменение поведения JVM (например, введение ограничений времени выполнения, какие потоки разрешено блокировать или изменять) или полную реализацию Isolates JSR. Это выходит за рамки того, что я считал «честной игрой».

Итак, давайте пока исключим случай ненадежного кода. Или, по крайней мере, признать, что вредоносный код может сделать что-то, что делает его небезопасным для безопасного уничтожения, и отложить эту проблему в сторону.

Итак, давайте пока исключим случай ненадежного кода. Или, по крайней мере, признать, что вредоносный код может сделать что-то, что делает его небезопасным для безопасного уничтожения, и отложить эту проблему в сторону.

Итак, давайте пока исключим случай ненадежного кода. Или, по крайней мере, признать, что вредоносный код может сделать что-то, что делает его небезопасным для уничтожения, и отложить эту проблему в сторону.

19
ответ дан 26 November 2019 в 23:11
поделиться

Отсутствие безопасности проистекает из идеи критических секций

Take mutex

do some work, temporarily while we work our state is inconsistent

// all consistent now

Release mutex

. Если вы удалите поток, и он оказался в критическом разделе, то объект останется в несогласованном состоянии, это означает, что с этой точки небезопасно использовать.

Чтобы было безопасно убить поток, вам нужно понимать всю обработку того, что делается в этом потоке, чтобы знать, что в коде нет таких критических секций. Если вы используете код библиотеки, возможно, вы не сможете увидеть исходный код и знать, что это безопасно. Даже если сегодня безопасно, завтра может не быть.

(Очень надуманный) Пример возможной небезопасности. У нас есть связанный список, он не циклический. Все алгоритмы действительно быстрые, потому что мы знаем , что они не цикличны. Во время нашего критического раздела мы временно вводим цикл. Затем нас сдувает, прежде чем мы выходим из критической секции. Теперь все алгоритмы, использующие список, повторяются навсегда. Ни один автор библиотеки не стал бы этого делать! Откуда вы знаете? Вы не можете предполагать, что код, который вы используете, хорошо написан.

В примере, на который вы указываете, безусловно, можно написать функциональность requreid прерываемым способом. Больше работы, но можно быть в безопасности.

Я возьму флаер: не существует задокументированного подмножества объектов и методов, которые можно было бы использовать в отменяемых потоках, потому что ни один автор библиотеки не хочет давать гарантии.

Несомненно, можно написать функциональность requreid прерываемым способом. Больше работы, но можно быть в безопасности.

Я возьму флаер: не существует задокументированного подмножества объектов и методов, которые можно было бы использовать в отменяемых потоках, потому что ни один автор библиотеки не хочет давать гарантии.

Несомненно, можно написать функциональность requreid прерываемым способом. Больше работы, но можно быть в безопасности.

Я возьму флаер: не существует задокументированного подмножества объектов и методов, которые можно было бы использовать в отменяемых потоках, потому что ни один автор библиотеки не хочет давать гарантии.

10
ответ дан 26 November 2019 в 23:11
поделиться

Может быть, я чего-то не знаю, но, как сказал java.sun.com , это небезопасно, потому что все, что обрабатывает этот поток, подвергается серьезному риску быть поврежденным. . Другие объекты, соединения, открытые файлы ... по очевидным причинам, например, «не закрывайте Word без предварительного сохранения».

Для этого примера find (...) я не Я действительно думаю, что было бы катастрофой просто отбросить его с помощью бессмысленного .stop () ...

1
ответ дан 26 November 2019 в 23:11
поделиться

Все формы управления параллелизмом могут быть обеспечены с помощью примитивов синхронизации Java путем создания более сложных элементов управления параллелизмом , которые соответствуют вашей проблеме.

Причины прекращения поддержки четко указаны в предоставленной вами ссылке. Если вы согласны принять причины, почему, то не стесняйтесь использовать эти функции.

Однако, если вы решите использовать эти функции, вы также соглашаетесь с тем, что поддержка этих функций может прекратиться в любое время.

Редактировать : Я повторю причину устаревания, а также способы их избежать.

Поскольку единственная опасность заключается в том, что объекты, на которые может ссылаться stop ed-поток, могут быть повреждены, просто клонируйте строку перед тем, как передать ее в поток .

-3
ответ дан 26 November 2019 в 23:11
поделиться

Модули Delphi не "принципиально сломаны". То, как они работают, способствует феноменальной скорости компилятора и способствует чистому дизайну классов.

Возможность распределять классы по модулям способом, который позволяет Prims / .NET, является подходом, который, возможно, фундаментально нарушен, поскольку способствует хаотической организации классов, позволяя разработчику игнорировать необходимость должным образом спроектировать свою структуру, продвигая навязывание правил произвольной структуры кода, таких как «один класс на единицу», что не имеет технических или организационных достоинств в качестве универсального изречения.

В этом случае , Я сразу заметил идиосинхратию в дизайне классов, проистекающую из этой дилеммы круговых ссылок.

То есть, зачем фигуре когда-либо иметь какую-либо необходимость ссылаться на доску?

Если фигура взята с доски, такая ссылка не имеет смысла, или, возможно, действительные «MoveTargets» для удаленной фигуры только те, которые действительны для этой фигуры в качестве «стартовой позиции» в новой игре? Но я не думаю, что это имеет смысл, кроме произвольного обоснования случая, который требует, чтобы GetMoveTargets поддерживал вызов со ссылкой на плату NIL.

Конкретное размещение отдельной фигуры в любой момент времени является свойством индивидуальная игра в шахматы, а также ДЕЙСТВИТЕЛЬНЫЕ ходы, которые могут быть ВОЗМОЖНЫМИ для любой данной фигуры, зависят от размещения ДРУГИХ фигур в игре.

TChessPiece. GetMoveTargets не требует знания текущего состояния игры. Это ответственность TChessGame . А TChessPiece не нуждается в ссылке на игру или доску для определения допустимых целей для перемещения из данной текущей позиции. Ограничения доски (8 рангов и файлов) являются константами предметной области, а не свойствами данного экземпляра доски.

Таким образом, требуется TChessGame , которая инкапсулирует знания, объединяющие понимание доски, фигур и - что особенно важно - правила, но доска и фигуры не нуждаются в знании друг друга ИЛИ игры.

Может показаться заманчивым поместить правила, относящиеся к разным фигурам в классе, для самого типа фигуры, но это это ошибка имхо, поскольку многие правила основаны на взаимодействии с другими фигурами, а в некоторых случаях и с конкретными типами фигур. Такое поведение «общей картины» требует определенной степени наблюдения (читай: обзора) всего состояния игры, что не подходит для конкретного класса фигур.

например, TChessPawn может определить, что допустимая цель перемещения - одна или две. квадраты вперед или один квадрат по диагонали вперед, если любой из этих диагональных квадратов занят. Однако, если движение пешки подвергает короля ситуации ПРОВЕРКИ, то пешка вообще не может быть перемещена.

Я бы подошел к этому, просто позволив классу пешки указывать все ВОЗМОЖНЫЕ цели для хода - на 1 или 2 поля вперед. и оба по диагонали вперед квадраты. Затем TChessGame определяет, какой из них действителен, исходя из занятости этих перемещаемых целей и состояния игры. 2 клетки вперед возможны только в том случае, если пешка находится на своем домашнем ранге, передние клетки заняты БЛОКИРОВАТЬ ход = недействительная цель, незанятые диагональные клетки ОБЕСПЕЧИВАЮТ ход, и если любой другой допустимый ход обнажает короля, то этот ход также недействителен.

Опять же, может возникнуть соблазн поместить общеприменимые правила в базовый класс TChessPiece (например, раскрывает ли данный ход Короля?), Но применение этого правила требует осведомленности об общем состоянии игры - то есть размещение других фигур - так что это более правильно относится как обобщенное поведение класса TChessGame , imho

В дополнение к перемещению целей, фигуры также должны указывать CaptureTargets, что в случае большинства фигур одно и то же, но в некоторых случаях совсем другое - хороший пример - пешка. Но опять же, что - если вообще есть - из всех возможных взятий является эффективным для любого данного хода, это - imho - оценка правил игры, а не поведение фигуры или класса фигур.

Как это имеет место в 99% случаев. В таких ситуациях (ime - ymmv) дилемму, возможно, лучше решить, изменив дизайн класса для лучшего представления моделируемой проблемы, не найдя способа втиснуть дизайн класса в произвольную файловую организацию.

У меня есть сервер, написанный на java, и если администратор этой службы хочет «холодного выключения», то просто НЕОБХОДИМО иметь возможность остановить все запущенные операции, несмотря ни на что. Согласованность состояния любого объекта не является проблемой, потому что все, что я пытаюсь сделать, это ВЫЙТИ. Как можно быстрее.

-1
ответ дан 26 November 2019 в 23:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: