科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道让你的Java程序只有一个进程实例在运行

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

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

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

作者:swings 来源:赛迪网技术社区 2007年12月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%>  
  { gf\Yt@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#ph\cm  
  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  
} (N$1n- \7  
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  
Copy code
#include <windows.h> @ 79ZF N%S  
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'  

hP C*!/CL  
>3GZIckE  
说明: &%BM#Ic4 m  
    以上程序用到了JNI的有关知识,其中生成的头文件我没有列出源代码. $;S 9J}vU  
    至于具体的JNI编程知识,我以前有相关文档说明. }&%w=(7  
    你可以再做相应的处理来达到激活先前打开的实例而不是弹出那个警告对话框. ?K%m1/ !  
    如果有更好的方法实现,欢迎你和我探讨,我的QQ:415764553 yj5w]HPZ  
    这里我把本程序的所有C++和Java代码都附上. 9r<6`8e ]  

 

查看本文来源
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章