我创建了一个类,允许我打开 Java 程序的单个实例。它使用打开 ServerSocket 的守护线程。如果 TCP 端口已被占用,则会在实例化时引发异常。
代码在linux和windows下都能正常运行。
这是我正在使用的代码:
public class SingleInstaceHandler extends Thread {
private static final Logger log = Logger.getLogger(IEPLC_Tool.class);
private boolean finished = false;
@SuppressWarnings("unused")
private ServerSocket serverSocket;
/*
* Constructor
* Generate the server socket.
* If the TCP door was busy throws IOException.
*/
public SingleInstaceHandler() throws IOException {
@SuppressWarnings("unused")
ServerSocket serverSocket = new ServerSocket(44331);
this.setDaemon(true);
this.start();
log.info("Server socket initialized"); //if commented out it works
}
public void run() {
synchronized (this) {
while (!finished) {
try {
log.debug("Server socket goes to sleep");
this.wait();
log.debug("Server socket waken up");
} catch (InterruptedException e) {
log.debug("ERROR while sending SocketThread2 in wait status");
e.printStackTrace();
System.exit(-1);
}
log.info("Server socket end");
}
}
}
public synchronized void shutdown() {
log.debug("SingleInstaceHandler shutdown() caled");
finished = true;
notifyAll();
}
}
有时端口并不保持忙碌......知道吗?
<小时/>进一步测试后更新:
运行许多其他测试。它表明,如果端口被另一个 SW 实例之类的东西占用,new ServerSocket(44331);
会抛出异常,但有时即使由于某种原因未占用端口,它也无法获取此资源。在这种情况下,不会启动任何异常,我可以打开任意数量的应用程序实例。也许我应该做一些其他操作来强制线程锁定端口...
有什么想法吗?
谢谢
斯特
最佳答案
由于您没有保留对 ServerSocket 的引用,因此它将有资格进行 GC。如果您使用的是 Oracle JDK,则套接字在 GC 时将被关闭 (java.net.PlainSocketImpl)。
关于java - 意外的套接字有时会关闭(或不打开),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7416365/