2014-03-06 87 views
0

我需要开发一个maven插件,它可以启动apache ftp-server,将其作为守护进程运行(不会暂停构建过程)并将其作为另一个目标停止。不幸的是我第一次尝试与守护线程失败:守护程序线程阻止JVM终止 - 可能的原因?

public class FtpServerDaemon 
{ 
    public static void main(final String[] args) throws Exception 
    { 
     Thread thread = new Thread(new Runnable() 
       { 
        @Override public void run() 
        { 
         org.apache.ftpserver.main.Daemon.main(args); 
        } 
       }); 

     thread.setDaemon(true); 
     thread.start(); 
     Thread.sleep(10000); 
    } 
} 

糟糕这里的事情是,JVM不会在10秒后结束,但它无限期地运行。如果Daemon.main是黑盒代码(但源代码为available),那么可以防止JVM在守护程序线程中终止?

+2

我的头顶上,我怀疑FTP服务器正在自己的线程。 – chrylis

+0

您可以采用线程转储来查看非守护程序线程是否处于活动状态 - 可能是'Daemon.main'的代码中的'server.start()'产生的...... – assylias

+0

守护程序线程不会阻止关机根据定义,你有一个线程,它是一个仍在运行的非守护进程。尝试使用'jstack {pid}'来查看哪些线程仍在运行 –

回答

0

FtpServer启动非守护线程并且它们仍在运行。如果一个线程是从守护进程线程派生的,那么新线程将最初从其父进程继承守护进程状态,但是可以覆盖它。例如:

Thread thread = new Thread(new Runnable() 
       { 
        @Override public void run() 
        { 

         Thread embeddedNonDaemon = new Thread(new Runnable() 
           { 
            @Override public void run() 
            { 
             while (true) 
             { 
              ; 
             } 
            } 
           }); 

         embeddedNonDaemon.setDaemon(false); 
         embeddedNonDaemon.start(); 
        } 
       }); 

     thread.setDaemon(true); 
     thread.start(); 
     Thread.sleep(5000); 

该代码也不会终止。

1

同意assylias和chrylis的评论。

而不是org.apache.ftpserver.main.Daemon.main(args);你可以尝试一些其他的代码吗?一个持续时间超过主线程睡眠时间的循环应该做,每n秒打印一个数字或其他东西。

我相信它必须正确终止。只是为了测试ftpserver是否阻止退出。

顺便说一下,如果一个守护进程线程产生一个子线程,子线程会自动设置为守护进程,对吗?那么为什么会这样呢?

+0

是的,如果我尝试while(true );而不是Daemon.main(args),它按预期工作:JVM在10秒后终止。 – kavai77

+0

@ toni77在下面,默认实现启动一个ThreadPoolExecutor,它们是非守护线程。 –