gpt4 book ai didi

java - 如何自动关闭 JMXConnectorServer

转载 作者:行者123 更新时间:2023-11-30 09:32:03 24 4
gpt4 key购买 nike

我正在尝试启动 JMXConnectorServer 以进行管理和调试。但是我不希望这个服务在最后一个非守护线程终止时阻止应用程序正常退出。

换句话说,我希望下面的程序立即终止:

public class Main {
public static void main(final String[] args) throws IOException {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
JMXServiceURL jmxUrl = new JMXServiceURL("rmi", null, 0);
JMXConnectorServer connectorServer =
JMXConnectorServerFactory.newJMXConnectorServer(jmxUrl, null, mbs);
connectorServer.start();
}
}

最佳答案

我玩类似的问题并写了这个类:

public final class HardDaemonizer extends Thread {

private final Runnable target;
private final String newThreadName;

public HardDaemonizer(Runnable target, String name, String newThreadName) {
super(name == null ? "Daemonizer" : name);
setDaemon(true);
this.target = target;
this.newThreadName = newThreadName;
}

@Override
public void run() {
try {
List<Thread> tb = getSubThreads();
target.run();
List<Thread> ta = new java.util.ArrayList<>(getSubThreads());
ta.removeAll(tb);
for (Thread thread : ta) {
thread.setName(newThreadName);
}
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException ex) {
Logger.getLogger(HardDaemonizer.class.getName()).log(Level.SEVERE, null, ex);
}
}

public static Thread daemonize(String daemonizerName, String newThreadName, Runnable target) {
HardDaemonizer daemonizer = new HardDaemonizer(target, daemonizerName, newThreadName);
daemonizer.start();
return daemonizer;
}

private static List<Thread> getSubThreads() {
ThreadGroup group = Thread.currentThread().getThreadGroup().getParent();
Thread[] threads = new Thread[group.activeCount()];
group.enumerate(threads);
return java.util.Arrays.asList(threads);
}
}

你可以这样使用它:

HardDaemonizer.daemonize(null, "ConnectorServer", new Runnable(){
@Override
public void run() {
try {
connectorServer.start();
} catch (IOException ex) {
Logger.getLogger(Ralph.class.getName()).log(Level.SEVERE, null, ex);
}
}
});

小心 - 这很棘手!


编辑

啊...这不是适合您的解决方案。它仅对连接器线程进行硬守护,并且当 jvm 停止时该线程将被终止。此外,您可以自定义此线程的名称。

或者,您可以在 daemonize 方法中添加标志 completed 并在循环中 hibernate ,直到连接器服务器启动。


简化

这是简化的守护程序,没有棘手的线程重命名:

public abstract class Daemonizer<T> extends Thread {

private final T target;
private boolean completed = false;
private Exception cause = null;

public Daemonizer(T target) {
super(Daemonizer.class.getSimpleName());
setDaemon(true);
this.target = target;
}

@Override
public void run() {
try {
act(target);
} catch (Exception ex) {
cause = ex;
}
completed = true;
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException ex) {
java.util.logging.Logger.getLogger(Daemonizer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
}

public abstract void act(final T target) throws Exception;

public static void daemonize(Daemonizer daemonizer) throws Exception {
daemonizer.start();
while (!daemonizer.completed) {
Thread.sleep(50);
}
if (daemonizer.cause != null) {
throw daemonizer.cause;
}
}
}

用法:

Daemonizer.daemonize(new Daemonizer<JMXConnectorServer>(server) {
@Override
public void act(JMXConnectorServer server) throws Exception {
server.start();
}
});

关于java - 如何自动关闭 JMXConnectorServer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12645155/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com