私は同様の問題で遊んで、このクラスを書きました:
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 が停止するとこのスレッドは強制終了されます。さらに、このスレッドの名前をカスタマイズできます。
または、フラグを追加し、コネクタ サーバーが起動するまでcompleted
ループ イン メソッドでスリープすることもできます。daemonize
簡素化
これは、トリッキーなスレッドの名前変更を行わない簡素化されたデーモン化プログラムです。
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();
}
});