可能重复:
java/shellscript code to find out if a jar file is already running on current machine
我很想获得一个跨平台的解决方案,但即使它只是unix,那也没关系。
简单的解决方案是从shell(Pseudocode)执行此操作(如果ps -aux | grep myJar | print {awk 2}。包含myPID,请不要运行myProgram。
现在不幸的是,我们的Linux团队不希望像生产中那样的脚本在生产中运行,因为它可以(诚然)有不良行为。
所以我需要的是能够运行文件,运行时看看是否正在运行另一个程序。如果程序已在运行并且低于该时间限制,则应该阻止程序运行。
一点例子:
Myprog.jar - 超时5分钟
Myprog.jar是一个每4分钟调用一次的cron,
第一次调用它启动时,第二次调用它仍在运行,但由于它没有超时,所以没关系。
如果在第三次检查结束时它仍在运行(执行后8分钟),它就会被杀死,之后它的过程会自动替换。
如果有人可以帮我理解如何做到这一点(我们一直试图设置一个锁定文件但成效有限)
谢谢!
答案 0 :(得分:3)
您可以在程序启动时使程序打开一个虚拟文件,以便用FileWriter进行书写,并保持文件打开直到程序完成。
当你现在启动你的程序的第二个实例时,它也会尝试打开这个文件进行写入,这将抛出IOException,因为只有一个进程可以同时拥有一个文件的写句柄时间。
答案 1 :(得分:2)
您可以将端口用作信号量。有关详细信息,请参阅this question。我认为端口将是一个很好的跨平台解决方案
答案 2 :(得分:1)
您可以在固定位置创建临时文件。
private static final File LOCK_FILE = new File("app.lock");
public static boolean checkIfAlreadyRunning()
{
return LOCK_FILE.exists();
}
public static void createLockFile()
{
LOCK_FILE.createNewFile();
Runnable shutDown = new Runnable()
{
public void run()
{
try
{
LOCK_FILE.delete();
} catch (Exception e) { /* Sad but true */ }
}
};
Runtime.getRuntime().addShutdownHook(new Thread(shutDown));
Thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
{
public void uncaughtException(Thread t, Exception e)
{
shutDown.run();
System.exit(-1);
}
});
}
答案 3 :(得分:1)
我遇到了完全相同的问题,解决起来非常棘手。基于文件和套接字的方法都可以工作,但是在某些操作系统上它会变得非常棘手(想想在多个终端服务器会话中有多个用户的Windows等)。
首先,确定只需要一个实例的范围。然后决定解决方案。
具有固定端口号的ServerSocket方法将允许您为每台计算机一个实例(可能不完全符合您的要求)。
可以定制锁定文件方法以在用户temp directoy中创建锁定文件,因此它为每个会话/用户提供一个实例。
我个人使用一种组合方法,其中锁定文件指定随机端口,第二个实例连接到该端口以将命令行参数传递给正在运行的实例。