如何在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中运行与主线程分开的线程?的主要内容,如果未能解决你的问题,请参考以下文章

java并发-线程池总结

Qt例子,线程间通信,如何在线程外部对线程进行控制,问题请看问题补充,多谢了先

delphi VCL显示问题 分线程与主线程的同步

将工作线程与主线程同步

工作线程如何在Nodejs中工作?

java 子线程 回调 主线程