Потоки Java: возможно ли просмотреть / приостановить / уничтожить определенный поток из другой Java-программы, работающей на той же JVM?

StackOverflow https://stackoverflow.com/questions/181615

  •  05-07-2019
  •  | 
  •  

Вопрос

У меня есть программа 'foo', запускающая разные потоки: fooT1, fooT2, .. fooTn.

Теперь, если я хочу написать другую программу 'bar', которая могла бы уничтожить поток fooTr, возможно ли это?

Причина: один из потоков fooTr отслеживает лицензию на продукт. Если этот поток убит; можно запустить этот продукт на неопределенный срок. И само убийство 'foo' допустимо как 'foo', поскольку именно это и делается по истечении срока действия лицензии.

Система: дистрибутив Fedora Linux

Примечание. Команды, запускающие JVM и программу foo, находятся в /etc/init.d, и любой, кто имеет хорошие знания о структуре rc.1 / rc.2 / rc.3, может изменить / добавить начальные параметры в это.

Надеюсь, мой вопрос понятен. Если нет, я всегда могу отредактировать его.

Это было полезно?

Решение

Насколько мне известно, это невозможно сделать напрямую. Однако вы могли бы подумать о создании некоторого сервиса на вашем 'foo', который можно вызывать из 'bar' для уничтожения потока. Есть, конечно, сотни способов реализовать это. Моей первой мыслью было бы сделать это с помощью RMI .

Другие советы

На самом деле отладчик Java позволяет вам убить поток, вставив в него исключение. Я просто пытался понять, как использовать эту функцию, чтобы убить поток, не уничтожая весь jvm, когда натолкнулся на этот вопрос. Если вы запускаете jvm с параметрами командной строки, такими как:

java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8888 your.app.Main

и подключите отладчик к чему-то вроде:

jdb -attach 127.0.0.1:8888

вы можете ввести:

threads

, чтобы получить список запущенных потоков, и использовать команду kill, чтобы уничтожить запущенный поток. Ситуация, в которой я сейчас не уверен, - это синтаксис этой команды kill, я попробовал очевидное:

kill 0xe2e new java.lang.IllegalArgumentException("er");

и я получаю сообщения:

killing thread: Swank REPL Thread
Thread not suspended
Expression must evaluate to an object

(" Нить Swank REPL " - это нить, которую я хочу удалить, и да, я сначала попытался приостановить ее;)

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

Вы можете сделать это даже без отдельного приложения. Напишите свой собственный класс запуска, который выполняет передачу параметров в исходный класс запуска приложения. Основной метод вашего класса, тем не менее, создает поток, который периодически проверяет список всех потоков (например, Thread.getAllStackTraces или Thread.enumerate ), находит нарушающий поток и вызывает stop () на нем. Хотя Thread.stop устарел, он все равно работает.

Другой вариант - запустить приложение под отладчиком Java, скажем, jdb , а затем приостановить / убить требуемый поток. Вы также можете добавить параметры для запуска приложения, чтобы JVM могла быть присоединена, затем присоединить jdb к работающей JVM и подозревать / уничтожать поток.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top