2009-12-11 2 views
41

Как отличить запущенные потоки Java и собственные потоки?Отличие между потоками Java и потоками ОС?

В Linux будет родительский процесс для каждого дочернего процесса, и они говорят, что 0 является родительским для всего процесса, будет ли родительский поток всех разветвленных потоков Java?

Как узнать, какой поток Java связан с потоком ОС (если поток Java вызывает собственный поток процесса).

Есть ли какое-либо соглашение об именах потоков Java и потоков ОС?

Можно ли приостановить или убить запущенные потоки Java из другого кода Java?

+0

Stephen C, я изучаю, как имена потоков Linux и именования Java связаны между собой. А также, как управление потоками JVM-потоков управляется в Linux. – karthi

ответ

61

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

В современной системе Linux (использующей NPTL) все потоки, относящиеся к процессу, имеют одинаковый идентификатор процесса и идентификатор родительского процесса, но разные идентификаторы потоков. Вы можете увидеть эти идентификаторы, запустив ps -eLf. Столбец PID - это идентификатор процесса, столбец PPID - это идентификатор родительского процесса, а столбец LWP - это идентификатор потока (LightWeight Process). «Основной» поток имеет идентификатор потока, который совпадает с идентификатором процесса, а дополнительные потоки будут иметь разные значения идентификатора потока.

Старые системы Linux могут использовать реализацию потоковой реализации «linuxthreads», которая не является полностью совместимой с POSIX, а не NPTL. В системе linuxthreads потоки имеют разные идентификаторы процессов.

Вы можете проверить, использует ли ваша система NPTL или linuxthreads, запустив библиотеку C (libc) в качестве автономной программы и посмотрев в разделе «Доступные расширения» на своем выходе. Он должен упомянуть либо «Native POSIX Threads Library», либо linuxthreads. Путь к библиотеке C варьируется от системы к системе: это может быть /lib/libc.so.6, /lib64/libc.so.6 (в 64-разрядных системах на базе RedHat) или что-то вроде /lib/x86_64-linux-gnu/libc.so.6 (на современных системах на базе Debian, таких как Ubuntu).

На уровне ОС у theads нет имен; они существуют только в рамках JVM.

Функция pthread_kill() C может использоваться для отправки сигнала в конкретный поток, который вы могли бы использовать, чтобы попытаться убить этот конкретный поток вне JVM, но я не знаю, как JVM ответит на него. Это может просто убить всю JVM.

+0

Спасибо Wyard, могу ли я назвать текущую нить и детали запроса runing thread? Я спрашиваю с точки зрения отладки. – karthi

+0

«Имя» для потока является специфичным для Java; чтобы увидеть такую ​​информацию, которую вам нужно будет подключить к JVM с помощью отладчика. Снаружи JVM вы можете видеть только его числовой идентификатор, который является его единственным идентификатором с точки зрения POSIX. – Wyzard

+0

Что нужно сделать, чтобы отобразить имя потока Java в командной строке оболочки? Если я подключу свой профилировщик или отладчик к запущенной JVM, смогу ли я получить запущенные имена потоков Java и предоставить сценарий Shell? – karthi

8

Нет стандарта; это полностью зависит от реализации Java, которую вы используете. Кроме того, не смешивайте «собственные потоки» и «собственные процессы». Процесс является изолированным объектом, который не может видеть в адресном пространстве других процессов. Поток - это то, что работает в адресном пространстве собственного процесса и которое может видеть в памяти других потоков одного и того же процесса.

Что вы видите в Linux - это что-то еще: некоторые версии Linux создают запись в таблице процессов для каждого потока родительского процесса. Эти «процессы» не являются реальными процессами (в смысле изоляции). Это потоки, которые могут быть перечислены с помощью команды ps. Вы можете найти процесс, который их создал, используя родительский PID (PPID).

4

Существует не общее решение, как потоки Java отображаются в потоки ОС, если вообще. Каждая реализация JVM может сделать это по-другому.

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

Можно ли приостановить или убить запущенные потоки Java из другого кода Java?

Если они работают на одном JVM, да, с stop(). Но это нехорошее решение и может работать, или нет. Прерывание() позволяет потоку безопасно закрыться.

Невозможно убить темы за пределами JVM, о которых я знаю. Если ОС действительно поддерживает уничтожение потоков, я бы не ожидал, что приложение Java будет работать правильно после этого!

5

Может ли работает Java потоки могут быть приостановлено или убит из другого Java кода?

В теории да. На практике методы Thread.kill() и Thread.suspend() устарели, поскольку они являются небезопасными, за исключением случаев с очень ограниченными ситуациями. Основная проблема заключается в том, что уничтожение или приостановка потока Java, скорее всего, испортит другие потоки, которые зависят от него, и общие структуры данных, которые могли быть посередине обновления.

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

+0

Вы можете просто выполнить команду Linux из своего Java-кода, чтобы убить определенный поток, работающий под определенной JVM. Вы даже можете сделать это в Windows. Но я думаю, вы, вероятно, правы, что просто разрушит родительскую JVM этого потока. Если вы контролируете обе программы, вы, вероятно, должны разработать какие-то вызовы IPC, чтобы потоки в другом процессе прекратили безвозмездно. – PSIXO

Смежные вопросы