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

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

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

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

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

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

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

Ответы [ 4 ]

13 голосов
/ 17 мая 2009

На самом деле отладчик 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 Thread» - это нить, которую я хочу уничтожить, и да, я пытался сначала ее приостановить;)

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

4 голосов
/ 08 октября 2008

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

3 голосов
/ 09 октября 2008

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

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

1 голос
/ 08 октября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...