Hazelcast阻止JVM终止

时间:2013-09-09 15:30:14

标签: java multithreading jvm hazelcast

我们在传统Java集群应用程序中使用Hazelcast 2.6.2。当应用程序停止时,JVM不再终止。它似乎是由Hazelcast线程没有被标记的守护进程引起的。我没有找到通过Hazelcast API来标记守护进程的方法。

是否有建议的解决方案来阻止Hazelcast阻止JVM终止?

此致

4 个答案:

答案 0 :(得分:2)

查看Hazelcast Javadocs,我发现有shutdownAll();方法。引用javadocs:

  

关闭此JVM上所有正在运行的Hazelcast实例,包括运行时的默认实例。它不会关闭集群的所有成员,只会关闭在此JVM上运行的成员。

如果你没有关闭它,我怀疑那里有非守护程序线程没有被终止,这将阻止JVM关闭。

答案 1 :(得分:1)

在Tomcat中,我通过server.xml添加了一个生命周期监听器。

<Listener className="com.mycompany.StartupHandler" DEBUG="false"/>

My StartupHandler.class放在$ TOMCAT_HOME / lib /的一个jar中,它包含这个片段,当检测到Tomcat关闭时触发Hazelcast关闭:

public void lifecycleEvent(LifecycleEvent lifecycleEvent) {
    String eventType = lifecycleEvent.getType();
    if (eventType.equals(Lifecycle.BEFORE_STOP_EVENT)) {
        com.hazelcast.core.Hazelcast.shutdownAll();
    }
}

其他Web服务器应该有类似的关闭挂钩,您可以自动调用Hazelcast.shutdownAll()。

有关同一主题的原始Hazelcast主题,请参阅https://github.com/hazelcast/hazelcast/issues/718。感谢此处提示调用Hazelcast.shutdownAll()。这个想法加上我的Tomcat关闭钩子应该足以解决这个问题,希望你也觉得它很有用。

答案 2 :(得分:0)

这是一种检测JVM关闭的Tomcat独立方法。它使用非守护程序线程轮询守护程序线程以检测JVM何时关闭(JVM自动关闭守护程序线程)。轮询代码中的静态IS_SHUTDOWN标志,或在此处内联对Hazelcast.shutdownAll()的调用。请注意竞争条件,因为如果您尝试在启动之前关闭Hazelcast,那么它会在您的日志中引发异常。例外并没有破坏任何东西,但它看起来很难看。

/**
 * Non-Daemon thread monitors a sacrificial, low-priority, daemon thread
 * to detect when JVM is shutting down, so shutdown hooks can be invoked.
 * @author justin.cranford
 */
public class ThreadUtil {
    public static boolean IS_SHUTDOWN = false;  // threads can poll this flag, or inline below where flag is set
    private static final Thread DAEMON_THREAD = new Thread() {
        public void run() {
            while (true) {
                try {
                    Thread.sleep(Long.MAX_VALUE);   // sleep forever
                } catch(Exception e) {}
            }
        }
    };
    private static final Thread NONDAEMON_THREAD = new Thread() {
        public void run() {
            while (true) {
                if (!DAEMON_THREAD.isAlive()) { // poll forever, until daemon thread dies
                    ThreadUtil.IS_SHUTDOWN = true;
                    return;
                }
                try {
                    Thread.sleep(1000); // poll every 1000msec = 1sec
                } catch(Exception e) {}
            }
        }
    };
    static {
        DAEMON_THREAD.setName("ShutdownMonitorNonDaemonThread");
        DAEMON_THREAD.setPriority(Thread.MIN_PRIORITY);
        DAEMON_THREAD.setDaemon(true);
        DAEMON_THREAD.start();
        try {
            Thread.sleep(3000); // wait 3000msec = 3sec before monitoring
        } catch(Exception e) {}
        NONDAEMON_THREAD.setName("ShutdownMonitorDaemonThread");
        NONDAEMON_THREAD.setPriority(Thread.MIN_PRIORITY);
        NONDAEMON_THREAD.setDaemon(false);
        NONDAEMON_THREAD.start();
    }
}

答案 3 :(得分:0)

正如大家所说,hazelcastInstance.shutdownAll()就是解决方案。

但是,我想在Hazelcast中获得一个新功能 - 同时提供恶魔客户端。有许多用例需要在应用程序结束后立即关闭缓存实例。