如何在Java中运行与主线程分开的线程?
Posted
技术标签:
【中文标题】如何在Java中运行与主线程分开的线程?【英文标题】:How to run a thread separate from main thread in Java? 【发布时间】:2011-04-29 15:41:33 【问题描述】:目标是能够从主类中调用单独线程的执行。
一些上下文: 我有一个必须运行进程的程序。 进程(一个 cmd 进程) 应该仅在主程序执行完毕并从内存中卸载时运行。
我应该在主类中包含哪些代码?
【问题讨论】:
我知道这已经晚了,但您是否将ProcessBuilder
视为不同的选项?
【参考方案1】:
如果您的意思是:如何启动一个不会在我的 JVM(Java 程序)结束时结束的 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();
这将确保如果 main() 线程结束,它也会终止 myThread。
但是,您可以从 java 启动不同的 JVM,为此您可能需要查看以下问题: Launch JVM process from a Java application use Runtime.exec?
【讨论】:
调用 myThread.start() 之后,myRunnable 会发生什么?还可以像往常一样与它交互吗(例如调用 run() 之外的方法)?【参考方案2】:创建一个单独的线程来执行你的外部程序:
class MyRunner implements Runnable
public void run()
Runtime.exec("your cmd")
然后在你的 main() 中启动线程:
MyRunner myRunner = new MyRunner();
Thread myThread = new Thread(myRunner);
myThread.start();
这样您的主程序将继续运行,而您的后台线程将启动一个外部进程并在该程序退出时退出。
【讨论】:
【参考方案3】:我不完全确定您是否可以使用实现 Thread 的常规方法在 Java 中创建一个“分离”线程并使用 run() 启动它。
您可能需要使用 Runtime.exec()
派生一个线程,将 java 作为完全独立的进程而不是作为线程运行。
【讨论】:
我使用 Runtime.exec() 来运行进程,但是在我的主程序没有完成之前,该进程不会开始工作(但他是 UP 并且有点挂起之类的)。 如果你运行的是*nix,我相信你可以通过在命令后面加上一个&来分离进程:top &
也许你可以使用cygwin?您是说您可以在 Windows 中创建一个新进程,但只要您的主程序正在运行,它就会暂停?如果是这样,听起来他们几乎是在争夺资源。你可以分叉一个不同的进程,比如显示一个大文件的内容,所以确保它们没有争夺资源?
SO上有很多相关的帖子:***.com/search?q=windows+runtime+java
稍后我会尝试你关于 ubuntu 中的 & 符号的提示。您提供的链接对我的问题没有太多帮助,抱歉 xD【参考方案4】:
要生成一个在 JVM 终止后仍然存在的进程,您需要使用 Runtime.exec()
。由于您希望它在您的主进程结束后运行,因此您可以通过两种方式实现它:
1) 如果您只想处理在干净关机期间运行,那么您可以这样做:
public static void main(String[] args)
doThisProgramsStuff();
spawnSecondProcess();
2) 或者,如果您希望进程在不正常关闭的情况下运行(或者如果它是一个 GUI 应用程序),那么您可以添加一个关闭挂钩:
public static void main(String[] args)
Runtime.getRuntime().addShutdownHook(new Thread()
public void run()
spawnSecondProcess();
);
doThisProgramsStuff();
然而,这一切都存在问题。一旦 JVM 终止,子进程将没有附加标准输入/输出,因此它可能会填充它的输出缓冲区并阻塞。您需要做一些事情来确保不会发生这种情况,方法是确保进程不会向这些流产生输出,或者执行 Windows 等效的重定向到 /dev/null。
【讨论】:
【参考方案5】:听起来你想要一个调用第一个程序的脚本,然后当第一个程序完成时,它会调用第二个程序。
类似
program1
program2
编辑:要并行运行这两个任务,您可以这样做
program1 &
program2
在 bash/unit shell 中。
或在dos shell中
start program1
program2
【讨论】:
其实不是。我有主类,这使我成为 1 个进程,并且该进程不应该阻塞主程序(我的想法)并且必须与主类分开做他的工作。 您已声明您需要“该进程(一个 cmd 进程)仅在主程序完成并从内存中卸载时运行”。使用 Runtime.exec() 在第一个进程完成之前和卸载之前启动第二个进程。 您最后的评论建议您希望两个进程同时运行。以上是关于如何在Java中运行与主线程分开的线程?的主要内容,如果未能解决你的问题,请参考以下文章