首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何优雅地停止java进程?

如何优雅地停止java进程?
EN

Stack Overflow用户
提问于 2008-10-10 13:17:36
回答 7查看 134.4K关注 0票数 90

如何在Linux和Windows中优雅地停止Java进程?

什么时候调用Runtime.getRuntime().addShutdownHook,什么时候不调用呢?

那么终结器呢,它们在这里有帮助吗?

我可以从shell向Java进程发送某种信号吗?

我正在寻找更好的便携式解决方案。

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2008-10-10 15:47:23

在VM未被强制终止的所有情况下,都会执行关闭钩子。因此,如果您发出一个“标准”kill (来自kill命令的SIGTERM),那么它们将被执行。类似地,它们将在调用System.exit(int)之后执行。

但是,如果是硬杀(kill -9kill -SIGKILL),那么它们就不会执行。同样(显然),如果你从计算机中拔出电源,将其放入一大桶沸腾的熔岩中,或者用大锤将CPU打成碎片,它们就不会执行。不过,您可能已经知道了。

Finalizer确实也应该运行,但最好不要依赖于它来进行关机清理,而是依靠你的关机钩子来干净地停止事情。而且,和往常一样,要小心死锁(我见过太多的关闭钩子挂起了整个过程)!

票数 84
EN

Stack Overflow用户

发布于 2008-10-16 14:36:02

好了,在我选择了使用"Java监控和管理“的所有可能性之后

Overview is here

这允许您以相对简单的方式从一个应用程序控制另一个应用程序。您可以从脚本调用控制应用程序,以便在终止受控应用程序之前优雅地停止它。

以下是简化的代码:

控制的应用程序:

使用以下VM参数运行它:

-Dcom.sun.management.jmxremote

-Dcom.sun.management.jmxremote.port=9999

-Dcom.sun.management.jmxremote.authenticate=false

-Dcom.sun.management.jmxremote.ssl=false

代码语言:javascript
代码运行次数:0
运行
复制
//ThreadMonitorMBean.java
public interface ThreadMonitorMBean
{
String getName();
void start();
void stop();
boolean isRunning();
}

// ThreadMonitor.java
public class ThreadMonitor implements ThreadMonitorMBean
{
private Thread m_thrd = null;

public ThreadMonitor(Thread thrd)
{
    m_thrd = thrd;
}

@Override
public String getName()
{
    return "JMX Controlled App";
}

@Override
public void start()
{
    // TODO: start application here
    System.out.println("remote start called");
}

@Override
public void stop()
{
    // TODO: stop application here
    System.out.println("remote stop called");

    m_thrd.interrupt();
}

public boolean isRunning()
{
    return Thread.currentThread().isAlive();
}

public static void main(String[] args)
{
    try
    {
        System.out.println("JMX started");

        ThreadMonitorMBean monitor = new ThreadMonitor(Thread.currentThread());

        MBeanServer server = ManagementFactory.getPlatformMBeanServer();

        ObjectName name = new ObjectName("com.example:type=ThreadMonitor");

        server.registerMBean(monitor, name);

        while(!Thread.interrupted())
        {
            // loop until interrupted
            System.out.println(".");
            try 
            {
                Thread.sleep(1000);
            } 
            catch(InterruptedException ex) 
            {
                Thread.currentThread().interrupt();
            }
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    finally
    {
        // TODO: some final clean up could be here also
        System.out.println("JMX stopped");
    }
}
}

控制应用程序:

使用stop或start作为命令行参数运行它

代码语言:javascript
代码运行次数:0
运行
复制
public class ThreadMonitorConsole
{

public static void main(String[] args)
{
    try
    {   
        // connecting to JMX
        System.out.println("Connect to JMX service.");
        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:9999/jmxrmi");
        JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
        MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();

        // Construct proxy for the the MBean object
        ObjectName mbeanName = new ObjectName("com.example:type=ThreadMonitor");
        ThreadMonitorMBean mbeanProxy = JMX.newMBeanProxy(mbsc, mbeanName, ThreadMonitorMBean.class, true);

        System.out.println("Connected to: "+mbeanProxy.getName()+", the app is "+(mbeanProxy.isRunning() ? "" : "not ")+"running");

        // parse command line arguments
        if(args[0].equalsIgnoreCase("start"))
        {
            System.out.println("Invoke \"start\" method");
            mbeanProxy.start();
        }
        else if(args[0].equalsIgnoreCase("stop"))
        {
            System.out.println("Invoke \"stop\" method");
            mbeanProxy.stop();
        }

        // clean up and exit
        jmxc.close();
        System.out.println("Done.");    
    }
    catch(Exception e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}

就这样。:-)

票数 47
EN

Stack Overflow用户

发布于 2009-06-17 15:19:04

另一种方式:您的应用程序可以打开服务器socet并等待收到的信息。例如,一个带有“魔术”单词:)的字符串,然后反应生成shutdown: System.exit()。您可以使用telnet等外部应用程序将此类信息发送到套接字。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/191215

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档