一个程序可以在内存里面存在多个运行实例,比如,你可以打开多个微软的Word程序.但是,有些时候我们需要控制程序运行的实例只有一个,也就是说,该程序同一时刻在内存里面运行的只有一个实例.这样当这个程序在内存中已经存在一个运行实例而用户又再次运行了该程序的时候,有两种结果,第一种结果是结束目前的运行实例,打开新运行的实例;第二种就是让新运行的实例退出,原有的运行实例继续运行.
原理
因为任何时候只有一个实例,所以在实现这种功能的时候必须借助只能被独享的资源.如果我们的程序是基于某个平台的,那么就可以借助操作系统的内核对象来完成,比如Windows操作系统就提供了CreateMutex这个API来创建一个独享的内核对象.但是因为要考虑平台无关,Java程序的实例控制不应该使用系统的内核对象来完成,那么我们就必须找到其它的、可以独享的资源.实际上,一台机器无论是在什么操作系统上,网络端口都是独享的,也就是说基于网络端口这个独享的原理,我们可以很方便地让我们的Java程序实现在内存里面只有一个运行实例这个功能,而且这个功能的实现是与平台无关的.
实现
我们先来看看第一种情况是如何实现的,也就是说如果系统中已经存在运行实例的话,那么结束原有的运行实例,让新实例运行.这个实现实例控制的Java类也是一个线程,具体的实现如下: import java.net.*;public class InstanceControl extends Thread { public void run() { try{ Socket sock = new Socket("127.0.0.1",22222); //创建socket,连接22222端口 } catch (Exception e) {} try{ ServerSocket server = new ServerSocket(22222);//创建socket,在22222端口监听 server.accept(); //等待连接 server.close(); //有连接到来,也就是说有新的实例 System.exit(0); //这个实例退出 }catch (Exception e) { e.printStackTrace(); } }}下面这个Java程序的程序入口是没有实例控制功能的: public class ProgramMain { public static void main(String argv[]) { mainFrame frame = new mainFrame(); }}现在想加入实例控制,只需要添加两行代码,添加后代码如下所示: public class ProgramMain { public static void main(String argv[]) { InstanceControl ic = new InstanceControl(); ic.start(); mainFrame frame = new mainFrame(); }}在这个基础上,要实现第二种情况,也就是已经有实例运行的情况下,新的实例退出,保持原有的运行实例,就只需要一点小的改动了.具体的实现如下: import java.net.*;public class InstanceControl2 extends Thread { public void run() { try{ Socket sock = new Socket("127.0.0.1", 22222);//创建socket,连接22222端口 System.exit(0); //连接成功,说明有实例存在,则退出 }catch (Exception e) {} try{ ServerSocket server = new ServerSocket(22222);//创建socket,连接22222端口 while (true) { server.accept(); //接受连接请求 } }catch (Exception e) { e.printStackTrace(); } }}这个类的使用方法和第一种情况的那个类是一样的,只需要在原有的代码上加入两行代码即可: InstanceControl2 ic = new InstanceControl();ic.start();扩展上面的程序也许有一个小bug,就是如果程序在开始运行时ServerSocket监听的端口已经被其它程序占用,那么程序的运行就会受到影响.所以程序的端口应该尽量取得大一些,在这种情况下其它程序占用这个程序使用的端口的概率是可以忽略不计的.同时,还可以做两种扩展,第一种是把端口写在配置文件中,可通过读配置文件得到端口,这样就能够在其它程序占用目前端口的情况下改变这个程序使用的端口.还有一种是在运行的时候用两个InstanceControl类分别在两个端口监听,只要有一个InstanceControl类得到连接就做出响应,这样两个端口都被其它程序占用的概率就更加的微乎其微了.

转载于:https://www.cnblogs.com/521taobao/archive/2012/03/17/2402485.html

让Java程序只运行一个实例相关推荐

  1. 转:让程序只运行一个实例的四种方法

    先留着以后有用. 让程序只运行一个实例的四种方法 综述:让一个程序只运行一个实例的方法有多种,但是原理都类似,也就是在程序创建前,有窗口的程序在窗口创建前,检查系统中是否已经设置了某些特定标志了,如果 ...

  2. Qt应用程序只运行一个实例

    在实际应用中,我们经常需要让应用程序只有一个实例,再打开新的文档或者页面时,只是替换现在的窗口或者新打开一个标签,而不是重新启动一次应用程序.Qt中是否可以做到这样呢,答案是肯定的,因为Qt本身可以直 ...

  3. 只运行一个实例的方法

    在VC++ 中编程中,只运行一个实例的方法主要有两类: 1 遍历当前的所有窗口,查找相同的实例.为了便于查找,一般要事先设一个查找标志. 2 利用系统提供的互斥对象或信标,直接让系统抑制重复的实例. ...

  4. 限制程序只打开一个实例(转载)

    当我们在做一些管理平台类的程序(比如Windows的任务管理器)时,往往需要限制程序只能打开一个实例.解决这个问题的大致思路很简单,无非是在程序打开的时候判断一下是否有与自己相同的进程开着,如果有,则 ...

  5. 只运行一个实例的写法

    有时我们需要只允许运行应用程序的一个实例,当进程启动时,如果发现应用程序的一个实例在运行,就自动停止运行.我们通常通过Mutex互斥体在Main函数中实现,通常的写法是: [STAThread] st ...

  6. 让你的程序只能运行一个实例

        先说一个循环系统进程的方法吧,             //首先取得你的程序当前进程             Process current = Process.GetCurrentProce ...

  7. 使用互斥体使程序只运行一个

    何为互斥体 引用了百科的话 互斥体实现了"互相排斥"(mutual exclusion)同步的简单形式(所以名为互斥体(mutex)).互斥体禁止多个线程同时进入受保护的代码&qu ...

  8. c#,Winform同一系统中只运行一个实例。

    代码 using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; na ...

  9. linux 只运行一个实例 互斥锁,Linux多线程4-1_互斥量

    //包含头文件 int pthread_mutex_destroy(pthread_mutex_t *mutex); int pthread_mutex_init(pthread_mutex_t *r ...

最新文章

  1. 第九周项目一-深复制体验(1)
  2. 密码学基础知识(五)序列密码
  3. 关于Matconvnet中Conv-ReLU-Pool-NormBatch的总结与思考
  4. VTK:图片之ImageAccumulate
  5. ambari 2.5.0源码编译安装
  6. [005] .NET 的执行模型
  7. ubuntu 电源按钮操作_电源菜单和按笔记本电脑电源按钮时缺少休眠
  8. 面试题17: 打印从1到最大的n位数
  9. 多智能体强化学习(一) IQL、VDN、QMIX、QTRAN算法详解
  10. git教程——安装和环境配置(1)
  11. 微软认证-新的MCSE和MCSA考试详解
  12. 吃货联盟订餐管理系统
  13. 双眼融合训练一个月_双眼视觉是什么?为什么要进行视功能训练?
  14. Python面向对象子类中重用父类的属性
  15. 如何修复Kindle频繁自动锁屏和解锁
  16. 使用Cluster API提供裸金属Kubernetes
  17. java word 图片不显示_POI用addPicture插入图片到word里面无法显示
  18. 【用户——提权——权限管理】
  19. 浅谈微博App在网站推广中的应用
  20. 佩奇:Google将投入巨资开发前瞻性…

热门文章

  1. nodejs安装及环境配置(windows系统)
  2. “.中国”域名注册总量超26.6万:11月份净减193个
  3. Delphi XE5 for Android (十)
  4. CentOS下实现postgresql开机自启动
  5. 【Vegas原创】Oracle每日export的脚本(Windows版)
  6. 零基础Java学习之封装
  7. Kraken2 物种序列比对 注释
  8. Idea 启动项目 很慢,总会到某个点进行延迟卡顿。
  9. (C#) GDI+简单绘图画直线
  10. java 之 学习过程中遇到的大佬博客