我试图通过绑定ServerSocket
来阻止启动java应用程序的多个实例。
目前我正在我的主要执行它,如下所示:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(65535, 10);
showFrame();
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
}
它在Eclipse中不起作用我仍然可以打开该应用程序的两个实例。
答案 0 :(得分:2)
有一些使用网络套接字的人。
使用独占锁定文件似乎更可靠。
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
// http://jimlife.wordpress.com/2008/07/21/java-application-make-sure-only-singleone-instance-running-with-file-lock-ampampampampamp-shutdownhook/
public class AppLock {
private static File f;
private static FileChannel channel;
private static FileLock lock;
public static boolean lock() {
try {
String directory = Utils.getUserDataDirectory();
String fileName = "jstock.lock";
Utils.createCompleteDirectoryHierarchyIfDoesNotExist(directory);
f = new File(directory + fileName);
// Do we need these code?
//if (f.exists()) {
// f.delete();
//}
channel = new RandomAccessFile(f, "rw").getChannel();
lock = channel.tryLock();
if(lock == null) {
channel.close();
return false;
}
} catch (FileNotFoundException ex) {
log.error(null, ex);
} catch (IOException ex) {
log.error(null, ex);
}
return true;
}
public static void unlock() {
// release and delete file lock
try {
if (lock != null) {
lock.release();
channel.close();
f.delete();
}
} catch(IOException e) {
log.error(null, e);
}
}
private static final Log log = LogFactory.getLog(AppLock.class);
}
public static void main(String args[]) {
if (false == AppLock.lock()) {
System.exit(0);
}
installShutdownHook();
...
}
private static void installShutdownHook() {
Runnable runner = new Runnable() {
@Override
public void run() {
AppLock.unlock();
}
};
Runtime.getRuntime().addShutdownHook(new Thread(runner, "Window Prefs Hook"));
}
请注意,我从开源项目中选择代码段:AppLock.java
答案 1 :(得分:2)
Java代码。把它放到一个名为Main.java的文件中:
import java.net.*;
import java.io.*;
public class Main{
public static void main(String args[]){
ServerSocket socket = null;
try {
socket = new ServerSocket(34567);
System.out.println("Doing hard work for 100 seconds");
try{ Thread.sleep(100000); } catch(Exception e){ }
socket.close();
}
catch (IOException ex) {
System.out.println("App already running, exiting...");
}
finally {
if (socket != null)
try{ socket.close(); } catch(Exception e){}
}
}
}
编译并运行
javac Main.java
java Main
在正常情况下进行测试:
运行程序。你有100秒的时间在另一个终端再次运行程序,它会说它已经运行了。然后等待100秒,它应该允许你在第二个终端运行它。
强制暂停程序后使用kill -9
进行测试<强>结论:强>
当程序不再运行时,操作系统会清除套接字占用。所以你可以确定程序不会运行两次。
<强>缺点强>
如果一些偷偷摸摸的人,或者一些顽皮的进程要绑定所有端口,或只是你的端口,那么你的程序将无法运行,因为它认为它已经在运行。