`
rcyl2003
  • 浏览: 231592 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

让你的Java程序只有一个进程实例在运行

阅读更多
用过金山词霸的人可能都会发现,当你把金山词霸打开,如果再去双击金山词霸 的快捷方式来启动它的时候,系统没有为我们再启动一个新的进程而是激活了前面我们已经打开的金山词霸程序,也就是说我们在一台计算机上同一时刻只能运行一 个金山词霸的实例。这样的软件现在也很多,典型的还有winamp,暴风影音等…..这样的好处可以避免用户因为误点而启动了原本不想启动的程序,同时也 使得我们的软件不会出现因为访问同一个资源而引起内部冲突问题。那么我们能不能在Java中也实现同样的功能呢? [xhse9_w  
    有的人可能会说了,我用单一模式去实现我的Java类不就好了吗?其实单一模式只是保证了一个类在其他的类中只能构造一个实例,并不能实现只有一个系统进 程在运行的功能。要实现这个功能的话,其实只要考虑一下用C++应该怎么样实现就好了,因为有了JNI,只要能用C++实现,稍微变一下的话就可以在 Java中实现了。下面我就以一个例子来说明我自己的实现方法。如果用户试图运行这个程序的第二个实例,那么就会弹出一个“只能有一个程序的实例被运 行!”的警告然后终止进程。具体的效果图如下: c! YR,)  
第一次运行程序
>&B'y4'a~  
打开第二个进程实例(第一个没有关闭)
ZrkMZkV Pf  
在Java程序中 C<2C}@[Nx  
先要定义一个将要在C++中具体实现的本地方法 ; "citGK  
[5ccn5}P"  
// 得到当前本程序正在运行的实例的数目 Y${kf-N/  
private native int getInstanceSum(); 6rYYb?-  
x&+ne  
然后再在Java程序的构造函数中去调用这个方法,如果函数返回值不为0,说明已经有实例在运行了,这个时候就要做相应的处理,否则正常进行构造函数的执行。具体的代码如下: }mlf DE  
Copy code
package com.caokai.jni; *28h  
m -]xcv  
import javax.swing.JFrame; G3+3pQ  
import javax.swing.JOptionPane; v"vT eWS  
p0jBC  
public class SingletonInstance extends JFrame { (f"5L  
  ;D VaS&  
  static = o g;Mrqt  
  { 3}=c;(  
    try #'+nR iu;V  
    { (/u}B  
        System.loadLibrary("SingletonInstance"); @6NyzQM  
    } Dq(F|0Qe  
    catch(Exception ex) k}}fI)y  
    { qz?Us &k  
        ex.printStackTrace(); smmk6uZg5  
    } [FVoM  
  } YR WrIZrm  
  zMx UuK  
  private native int getInstanceSum(); ~=r^]}:~  
      vI+BR7s;=  
  /** B-S5^ /<  
  * Method main tR*;fy(,0  
  * q7 zpuY?  
  * }|k"M|  
  * @param args @{M!j%/D  
  * 1$C}] U>  
  */ X&|L9uM.g  
  public static void main(String[] args) [D5k%>  
  { gfYt@6r  
    eK|B>/OV  
    SingletonInstance instance = new SingletonInstance(); .P,[:dRn  
    instance.pack(); In"v(KI8v  
    instance.setVisible(true); T;vnawG;  
  } KI ,*]Yr  
%=bz +x(07  
  /** =YrV`~$n&  
  * Method SingletonInstance 5HE]:%#)  
  * f [5n  
  * Defult constructor. $F7L]fh  
  */ =+`jxFMRl  
  public SingletonInstance() e !K]u}  
  { ch Q( >F  
    1_b3ht&M  
    super("SingletonInstance"); _9wJPNj  
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 5vK0FIf  
    checkRunning(); @oprP%n  
  } e{1842a  
  8 5EJL T  
  /** BLH916/  
  * Method checkRunning qBreaR$)oY  
  * ]O$}` Mh  
  * Check whether one instance of this program is running. (Mjp;d<2g  
  */ 7#phcm  
  public void checkRunning() {q](t n  
  { Sl*o:_r i  
    if(getInstanceSum() == 1) F<lTHL9  
    { R {%1 W  
        JOptionPane.showMessageDialog(null, "只能有一个程序的实例被运行!"); R=e~qBV)  
        System.exit(0); @p[e}_t(  
    } |x=NR=Ph*  
  }   [h&w 0z,Z  
} (Nn-  
fR`lj6  
v<-:uZi}T  
在C++程序中 9;"]M:Pv  
Z Y%RjF  
具 体的去实现前面声明的getInstanceSum() 函数。我们知道每一个windows程序在运行的时候,系统就会为其启动的进程分配4G的虚拟空间,然后再这个空间里面去启动进程里面的线程去完成程序具 体的功能。当然首先启动的就是main 函数的线程,就是主线程,然后再由主线程去启动其他的子现程。只要我们为主线程创建一个命名的互斥对象,这样当有第二个实例在运行的时候,当其创建同一个 名字的互斥对象时就会返回一个ERROR_ALREADY_EXISTS错误,如果我们调用GetLastError() 方法返回的错误和 ERROR_ALREADY_EXISTS相同,就说明已经有一个实例在运行了,这样就可以判断是否只有一个实例在运行了。具体的代码如下: llVA,v2(9  
@ 79ZF N%S #include <windowsh> 
N",`zL0>  
#include "SingletonInstance.h" O;AE{eM~_#  
Vwi;#%   
HANDLE hMutex; -=7 00  
hB0 n  
JNIEXPORT jint JNICALL Java_com_caokai_jni_SingletonInstance_getInstanceSum 0G>l>a4  
(JNIEnv *env, jobject obj) T!-_b"2?  
{ EqZX?Rgs,  
  hMutex = CreateMutex(NULL, FALSE, "SingletonInstance"); vz6o&Be[  
  if(hMutex) JF8ILB mO'  
  { ^nsvQ,F   
    if(GetLastError() == ERROR_ALREADY_EXISTS) E^hB]EC  
    { ;KCFA44 t  
        return JNI_TRUE; -L)M,{[@9  
    } I/B67v{]74  
  } M teFMzm  
c ,i=}e+  
  return JNI_FALSE; R|Nh7`=  
} 8 W Xw' 
 
分享到:
评论
1 楼 lliiqiang 2014-03-12  
程序实例是指同一个程序不能运行2次?怎么判断同一个程序?其实你复制一个是新程序还是改进的?当然用标识,但是这种容易冲突,所以就只是近似不可重复标识。除非你用一个系统统一程序编码。所以人为思考结果不可能绝对正确,只能相对人的想法相对正确.

相关推荐

    Java程序多进程运行模式的实例分析

    Java程序多进程运行模式的实例分析,实现进程管理。

    java 进程通信 实例(直接运行)

    本人写了一个java进程通信的工具jar,方便大家简单的使用java进程通信。 开启守护进程,获取消息: package com.test; import org.msun.process.ProcessMonitor; import org.msun.process.ProcessMonitor....

    Java程序多进程运行模式的实例分析.pdf

    Java程序多进程运行模式的实例分析.pdf

    java源码包实例源码JAVA开发源码50个合集.zip

    java源码包实例源码JAVA开发源码50个合集: Ajax框架 ZK.rar Java图书馆管理系统源程序.rar Java图片倒影效果实例源码.rar Java图片翻折,将图像压扁.rar Java坦克大战网络对战版源代码.rar Java声音播放程序源代码....

    JAVA上百实例源码以及开源项目源代码

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    JAVA上百实例源码以及开源项目

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    windows守护进程,开机自动重启,进程监测

    因为控制台程序出现过因为连接第三方服务超时直接挂掉(此时负载少了一个节点)以及服务器出现意外重启问题(该服务器所有节点宕机),所以需要一个进程守护程序。 也找过 现场的脚本、python的程序、pm2守护方式,...

    java实现内存动态分配

    每运行一个java程序会产生一个java进程,每个java进程可能包含一个或者多个线程,每一个Java进程对应唯一一个JVM实例,每一个JVM实例唯一对应一个堆,每一个线程有一个自己私有的栈。进程所创建的所有类的实例(也...

    Java范例开发大全(全书源程序)

    实例1 开发第一个Java程序 7 第2章 Java基础类型与运算符 实例2 自动提升 9 实例3 自动转换 10 实例4 常用基础类型之强制转换 11 2.2 运算符 12 实例5 算术运算符 12 实例6 关系运算符 13 实例7 逻辑...

    java范例开发大全

    实例1 开发第一个Java程序 7 第2章 Java基础类型与运算符(教学视频:39分钟) 9 2.1 基础类型 9 实例2 自动提升 9 实例3 自动转换 10 实例4 常用基础类型之强制转换 11 2.2 运算符 12 实例5 算术运算符 12 实例6 ...

    Java范例开发大全 (源程序)

     实例1 开发第一个Java程序 7  第2章 Java基础类型与运算符(教学视频:39分钟) 9  2.1 基础类型 9  实例2 自动提升 9  实例3 自动转换 10  实例4 常用基础类型之强制转换 11  2.2 运算符 12  实例5...

    Java开发技术大全(500个源代码).

    HelloWorldApp.java 第一个用Java开发的应用程序。 firstApplet.java 第一个用Java开发的Applet小程序。 firstApplet.htm 用来装载Applet的网页文件 第2章 示例描述:本章介绍开发Java的基础语法知识。 ...

    程序、进程、线程的区别

    系统运行一个程序即是一个进程从创建,运行到消亡的过程,也就是程序的一次执行过程。简单来说,一个进程就是一个计算机中运行的程序的实例。 线程:  线程是操作系统中的最小执行单元,负责当前进程中程序的执行...

    java开源包6

    在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程...

    java开源包9

    在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程...

    java开源包11

    在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程...

    java范例开发大全源代码

     实例1 开发第一个Java程序 7  第2章 Java基础类型与运算符(教学视频:39分钟) 9  2.1 基础类型 9  实例2 自动提升 9  实例3 自动转换 10  实例4 常用基础类型之强制转换 11  2.2 运算符 12 ...

    java开源包4

    在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程...

Global site tag (gtag.js) - Google Analytics