选择显示字体大小

让java程序只运行一个实例

出自:http://developer.cci.net.com 梁邦勇 2003年01月12日 18:04
一个程序可以在内存里面存在多个运行实例,比如,你可以打开多个微软的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类得到连接就做出响应,这样两个端口都被其它程序占用的概率就更加的微乎其微了


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons