处理多个应用程序实例
Dealing with multiple application instances
我正在开发 writes/reads 数据(文件)的应用程序(Java & JavaFX)。问题是我不想限制用户一次只能 运行 一个实例(我的应用程序),因为我真的想不出可靠的方法来做到这一点所以它适用于两个 Windows 和 Linux(例如服务器),听说过套接字和文件 - 两者都是有缺陷的 IMO。由于用户能够 运行 多个实例,writing/reading 数据(来自文件)看起来真的很乱,因为不能保证文件锁定在 Windows 和 Linux 上可靠地工作(FileLock 文档 -单击此处)。
总结:我无法限制我的应用程序的多个实例,但这会导致 writing/reading 数据(来自文件)出现问题。
有什么我遗漏的吗?也许还有其他方法可以解决我想不到的问题? “大”流行程序如何处理?
建议:使用套接字解决方案
您可以按照以下答案中概述的技术进行操作:
常见问题解答
解决一些额外的问题:
heard of sockets and files - both are defective IMO.
您表示您认为使用套接字来设置单实例应用程序对您来说效果不佳。你最有能力做出决定。
对于一些想要实现单实例的应用程序,链接问题的答案或其他评论中概述的 socket-based 或 file-based 解决方案就足够了。
"What happens if more than one user try to run the application? Won't they conflict on opening the socket?"
- Prevent launching multiple instances of a java application
并且:
Also, I can't be sure if chosen port (fixed, since all instances should check for one port) is being used by some other applications/processes
您可以通过增强链接问题中概述的 socket-based 解决方案来解决其中的一些问题。
增强套接字解决方案大纲
如果需要,您可以编写增强算法来处理其中的一些问题。
当另一个应用程序实例启动时,您尝试连接到 well-known 套接字上的当前实例。
检查对连接的响应。
如果它没有响应正确的协议响应(例如匹配用户和应用程序名称),则将端口增加 2 并重试。
再次测试响应直到:
您获得 app/user 组合的匹配项,然后向该应用程序发送信号以显示自身。
或
如果找不到匹配项,则在测试的开放端口上创建一个新实例。
我不是建议你这样做,只是说明这是可能的。
替代方案:OS本机服务
还有其他 OS-specific 机制来处理此问题,例如 Windows 或 Linux 服务,您可以根据需要进行调查,涉及这些方法并因 OS,这里就不详细讨论了。
对于 OS-specific 的解决方案,您通常会:
- 为您的应用创建原生包(例如使用
jpackage
)
- 安装它。
- 让安装程序将应用配置为服务
- 例如在 linux 上,创建一个
init.d
脚本,其中的 pid
文件通过 chkconfig
. 配置
- 服务在开机时启动并在关机时停止。
- 然后通过托盘图标或类似的东西访问该应用程序
- 交互方式通常 OS 版本特定。
备选方案:允许多个应用程序实例但使用单个数据库实例
您也可以考虑使用数据库而不是文件来存储数据,因为数据库系统可以帮助解决基于文件的解决方案可能出现的许多并发访问问题。多个客户端可以连接到数据库,数据库和您的应用程序代码可以处理数据访问上的锁定和冲突,以确保包含数据完整性。使用这样的解决方案,没有必要强制单个应用程序实例对用户来说是 运行(至少从数据完整性的角度来看)。
我正在开发 writes/reads 数据(文件)的应用程序(Java & JavaFX)。问题是我不想限制用户一次只能 运行 一个实例(我的应用程序),因为我真的想不出可靠的方法来做到这一点所以它适用于两个 Windows 和 Linux(例如服务器),听说过套接字和文件 - 两者都是有缺陷的 IMO。由于用户能够 运行 多个实例,writing/reading 数据(来自文件)看起来真的很乱,因为不能保证文件锁定在 Windows 和 Linux 上可靠地工作(FileLock 文档 -单击此处)。
总结:我无法限制我的应用程序的多个实例,但这会导致 writing/reading 数据(来自文件)出现问题。
有什么我遗漏的吗?也许还有其他方法可以解决我想不到的问题? “大”流行程序如何处理?
建议:使用套接字解决方案
您可以按照以下答案中概述的技术进行操作:
常见问题解答
解决一些额外的问题:
heard of sockets and files - both are defective IMO.
您表示您认为使用套接字来设置单实例应用程序对您来说效果不佳。你最有能力做出决定。
对于一些想要实现单实例的应用程序,链接问题的答案或其他评论中概述的 socket-based 或 file-based 解决方案就足够了。
"What happens if more than one user try to run the application? Won't they conflict on opening the socket?"
- Prevent launching multiple instances of a java application
并且:
Also, I can't be sure if chosen port (fixed, since all instances should check for one port) is being used by some other applications/processes
您可以通过增强链接问题中概述的 socket-based 解决方案来解决其中的一些问题。
增强套接字解决方案大纲
如果需要,您可以编写增强算法来处理其中的一些问题。
当另一个应用程序实例启动时,您尝试连接到 well-known 套接字上的当前实例。
检查对连接的响应。
如果它没有响应正确的协议响应(例如匹配用户和应用程序名称),则将端口增加 2 并重试。
再次测试响应直到:
您获得 app/user 组合的匹配项,然后向该应用程序发送信号以显示自身。
或
如果找不到匹配项,则在测试的开放端口上创建一个新实例。
我不是建议你这样做,只是说明这是可能的。
替代方案:OS本机服务
还有其他 OS-specific 机制来处理此问题,例如 Windows 或 Linux 服务,您可以根据需要进行调查,涉及这些方法并因 OS,这里就不详细讨论了。
对于 OS-specific 的解决方案,您通常会:
- 为您的应用创建原生包(例如使用
jpackage
) - 安装它。
- 让安装程序将应用配置为服务
- 例如在 linux 上,创建一个
init.d
脚本,其中的pid
文件通过chkconfig
. 配置
- 例如在 linux 上,创建一个
- 服务在开机时启动并在关机时停止。
- 然后通过托盘图标或类似的东西访问该应用程序
- 交互方式通常 OS 版本特定。
备选方案:允许多个应用程序实例但使用单个数据库实例
您也可以考虑使用数据库而不是文件来存储数据,因为数据库系统可以帮助解决基于文件的解决方案可能出现的许多并发访问问题。多个客户端可以连接到数据库,数据库和您的应用程序代码可以处理数据访问上的锁定和冲突,以确保包含数据完整性。使用这样的解决方案,没有必要强制单个应用程序实例对用户来说是 运行(至少从数据完整性的角度来看)。