今儿,想起来昨儿,解决的一问题,贴出来大家学习下,由于工作需要,学习,哈哈~!
手头的一个任务,是个java的SWT做的桌面应用程序,有一需求是,程序只能启动一个实例,二次启动会提示启动失败!网上转了一大圈几天也没找到比较理想的解决方法,在CSND等专业程序员网站上查找过,也没有找到!我正要放弃的时候,哈哈,被我找到了!
找了一写方案,总结起来就是,系统单一实例,就是查看共用资源,如果被占用,说明已经启动!有人说用单例模式,那是没有作用的!
网上找到的几种解决方案:
方案1:程序启动创建一临时文件,程序关闭删除文件,当第二次被启动的时候发现文件存在,说明程序正在运行,文件不存在说明程序没有启动!
问题:当程序非法关闭,没有执行到删除文件代码,文件就会一直存在,程序就永远启动不起来,只能手动删除,方法很好,但考虑问题不周全,容易出问题
推荐等级:★☆☆
方案2:程序启动监听端口,因为端口在一台计算机上一个端口号,只能同时被一个应用程序使用,利用了这个方法,当第二次启动程序时,发现端口被占用,说明程序正在运行!
问题:方法固然好,不过容易出现端口抢占的问题,与其他应用程序共用一个端口号,这样会影响其他的应用程序运行,解决方法也是有的,可以在配置文件里设置端口号,出现问题我就换,我换我换我换换换,所以使用此方案要选好端口哦!而且程序占用端口,而不使用端口,这也算是一种资源浪费,杀鸡何用宰牛刀!
推荐等级:★★☆
方案3:此方案就是我选择的终极方案拉,哈哈~!类似方案1,还解决了方案1遗留下来的问题,启动程序锁定指定文件,而不是创建和删除,当程序二次启动时要锁定文件时,无法访问该文件,说名程序正在运行!(为什么不直接使用文件而是使用文件锁来判断呢?即:在程序启动的时候生成一个文件而在程序退出时删除这个文件,只要判断该文件的存在与否就可以判断实例的运行情况。这是因为我们不能确保删除文件的操作一定能被执行到,程序是可能被强制关闭或异常退出的,而文件锁不同,它是作为系统资源分配给JVM的,一旦JVM当掉,其资源会一并被操作系统回收,因此对文件的锁定也会被消除。)这样不会干扰下次应用,还限制了只有一个实例!不得不说此方法妙啊!
问题:当锁定文件被删除时,找不到锁定文件,程序会抛出异常,解决方法可以在查找锁定文件时发现文件不存在,可以自动创建文件(另外,要注意,锁定文件千万不要锁定相应的资源文件,如程序相关的配置文件xml和一些properties,可能会发生意外事故,会把锁定的文件置空,里面的内容就飞拉,我是身有体会啊,我的log4j的配置文件啊!呜呜~~)
推荐等级:★★★★★
方案1、方案2方法可用单不好用,所以不提供相关代码,下面是方案3的demo代码,仅供参考!
public static boolean isLocking(){
try {
File flagFile = new File("config/lockInstance");
if (!flagFile.exists())
flagFile.createNewFile();
lock = new FileOutputStream("config/lockInstance").getChannel()
.tryLock();
if (lock == null)
return true;
} catch (Exception ex) {
logger.warn("程序正在运行中……");
}
return false;
}
***********************************************************************************************
[10月30日补充]
经过几天应用发现,第三种解决方案还是有问题会出现,如果应用被复制两份,那样程序就不能在次避免启动多例,考虑了下,如果想要避免这种情况,可以在指定位置创建锁定文件如:c:\windows\system32当然,这样做不是很道德,哈哈!