可能还有其他方法可以做到这一点,但我想使用一个空文件让应用程序的一个实例在给定时间运行。这将通过在启动应用程序时创建文件并让其他应用程序实例在检测到文件后立即退出来完成。
这种方法的问题在于,如果应用程序意外停止并且 ShutDownhook 被证明不可靠,文件可能会保留。
您将如何按预期完成这项工作?
可能还有其他方法可以做到这一点,但我想使用一个空文件让应用程序的一个实例在给定时间运行。这将通过在启动应用程序时创建文件并让其他应用程序实例在检测到文件后立即退出来完成。
这种方法的问题在于,如果应用程序意外停止并且 ShutDownhook 被证明不可靠,文件可能会保留。
您将如何按预期完成这项工作?
绑定到高编号端口但不监听。两个程序不能绑定到同一台机器上的同一个 TCP 端口。非常跨平台,但仍然有点杂乱无章。
创建文件并使用排他锁保持打开状态(即,不要通过FILE_SHARE_READ
等)。当第二个实例启动时,它会尝试打开文件,如果失败则意味着第一个实例仍在运行。
如果第一个崩溃,那么 Windows 将自动关闭所有文件句柄,因此第二个进程将出现,看到文件在那里,但因为它可以打开它,所以它知道第一个已经崩溃(这种技术也可以用于特殊对话框,“我看到这个应用程序的前一个实例崩溃了,你想恢复你的上一个会话吗?”或什么的)
你总是可以将你的Java程序包装在另一个程序中(不需要很复杂——甚至可以是一个shell脚本),它会检测到异常退出并删除文件。例如
if(!`java MyProgram`){
rm lockFile
}
这可能有点多。但是您可以启动一个 ServerSocket 并绑定到每个应用程序都知道的任意端口。如果端口可用,则应用程序将成功启动,否则将引发绑定异常并正常停止应用程序。
可能有比使用文件更好的方法来做到这一点,但使用这种方法,您可以将时间戳写入文件并使用计时器定期更新它。然后,当您的程序启动时,它可以将文件中的时间戳与当前时间进行比较,如果太接近则退出。这保证了您的程序无论如何终止都能够重新启动。
假设当应用程序退出时锁定将被释放并在启动时删除文件就可以了。请参阅下面的链接。
PS:我试过delete
在应用程序退出时使用,但它似乎失败了。