2010-10-23 2 views
15

Subj. Как запустить поток из основного класса BUT отдельно от этого класса?Java: Как запустить поток отдельно от основной программы/класса?

Итак, немного деталей: у меня есть одна программа, которая должна запускать процесс. Этот процесс (cmd-one) запускается только при завершении и выгрузке основной программы из памяти. И только после выгрузки основной программы этот процесс начинается с его работы.

Что следует добавить в программу?

+0

Я знаю, что это поздно, но вы посмотрели ['ProcessBuilder'] (http://docs.oracle.com/javase/8/docs/api/java/lang/ProcessBuilder.html) как другой вариант? – mkobit

ответ

30

Если вы имеете в виду: , то как я могу начать поток Java, который не закончится, когда моя JVM (java-программа) сделает?.

The answer is: you can't do that.

Поскольку в Java, если JVM выходит, все потоки выполняются. Это пример:

class MyRunnable implements Runnable { 
    public void run() { 
     while (true) { 
      doThisVeryImportantThing(); 
     } 
    } 
} 

выше программа может быть запущена с вашего основного потока, например, этот код:

MyRunnable myRunnable = new MyRunnable(); 
Thread myThread = new Thread(myRunnable); 
myThread.start(); 

Этот пример программы никогда не остановится, если что-то в doThisVeryImportantThing не закончится это нить. Вы можете запустить его в качестве демона, как в этом примере:

MyRunnable myRunnable = new MyRunnable(); 
Thread myThread = new Thread(myRunnable); 
myThread.setDaemon(true); // important, otherwise JVM does not exit at end of main() 
myThread.start(); 

Это позволит убедиться, если основной() нить заканчивается, он также будет прекращено MyThread.

Однако вы можете запустить другой JVM от Java, для этого вы можете проверить этот вопрос: Launch JVM process from a Java application use Runtime.exec?

+1

После вызова myThread.start(), что происходит с myRunnable? Можно ли все-таки взаимодействовать с ним, как обычно (например, вызвать методы, кроме run())? – aednichols

0

Похоже, что вы хотите сценарий, который вызывает первую программу, а затем, когда первый заканчивается, он вызывает вторую программу.

Что-то вроде

program1 
program2 

EDIT: Для выполнения этих двух задач параллельно вы можете сделать

program1 & 
program2 

в Баш/блок оболочки.

или дос оболочка

start program1 
program2 
+0

На самом деле нет. У меня есть основной класс, который делает мне 1 процесс, и этот процесс НЕ ДОЛЖЕН блокировать основную программу (что я думал) и должен выполнять свою работу отдельно от основного класса. – helpmepls

+0

Вы заявили, что вам нужен «Этот процесс (cmd-one) работает только при завершении и выгрузке основной программы из памяти». Использование Runtime.exec() запускает второй процесс до первого завершения и перед его выгрузкой. –

+0

Последний комментарий предполагает, что вы хотите, чтобы оба процесса запускались одновременно. –

0

Я не совсем уверен, что вы можете сделать «» отдельностоящую нить в Java с помощью обычных средств осуществления темы и пинать его с ходом().

Возможно, вам понадобится разветвить поток, используя Runtime.exec(), запуская java как полностью отдельный процесс, а не как нить.

+0

Я использую Runtime.exec() для запуска процесса, но этот процесс не начнет работать (но он UP и вроде приостановлен или что-то еще), пока моя основная программа не будет закрыта. – helpmepls

+0

Если вы используете * nix, я считаю, что вы можете отсоединить процесс, поставив амперсанд за команду: 'top &' –

+0

К сожалению, я использую окна. – helpmepls

0

Чтобы вызвать процесс, который выживает после того, как JVM заканчивается вам необходимо использовать Runtime.exec() ,Так как вы хотите, чтобы работать после того, как закончится ваш главный процесс, на самом деле есть два способа сделать это:

1) Если вы хотите обработать, чтобы запустить во время чистой остановки, то вы можете сделать это:

public static void main(String[] args) { 
    doThisProgramsStuff(); 
    spawnSecondProcess(); 
} 

2) или, если вы хотите, чтобы процесс работать даже с нештатной остановки (или, если это графический интерфейс приложения), то вы можете добавить выключение крючок:

public static void main(String[] args) { 
    Runtime.getRuntime().addShutdownHook(new Thread() { 
     public void run() { 
      spawnSecondProcess(); 
     } 
    }); 
    doThisProgramsStuff(); 
} 

Существует, однако, проблема с все это. После завершения JVM дочерний процесс будет иметь стандартный ввод/вывод, привязанный ни к чему, поэтому он может заполнить свои выходные буферы и блокировать. Вам нужно что-то сделать, чтобы убедиться, что этого не происходит, либо удостоверившись, что процесс не выводит выходные данные в эти потоки, либо выполняет эквивалент Windows для перенаправления на/dev/null.

4

Создать отдельный поток, который выполняет свою внешнюю программу:

class MyRunner implements Runnable{ 
    public void run(){ 
    Runtime.exec("your cmd") 
    } 
} 

затем начать нить в основной():

MyRunner myRunner = new MyRunner(); 
Thread myThread = new Thread(myRunner); 
myThread.start(); 

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

+0

Спасибо за этот ответ! – helpmepls

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