`
rcyl2003
  • 浏览: 237318 次
  • 性别: 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虚拟机(JVM)实例,每个实例都可以独立运行自己的任务。这种方式相比于单进程具有以下优势...

    如何使一个应用的多个实例运行在同一个进程空间

    总的来说,让多个应用实例运行在同一个进程空间是一种有效的优化手段,但也带来了复杂性。开发者需要具备扎实的并发编程知识,以及对操作系统和编程语言的深入理解。通过多线程或进程间通信,我们可以构建高效且协同...

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

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

    Java程序设计技巧与开发实例

    异常处理是Java中一个重要的错误处理机制,通过try-catch-finally结构可以捕获并处理运行时异常。学习者应熟悉不同类型的异常,如检查异常和运行时异常,以及何时使用throws关键字。 在实际开发中,设计模式是解决...

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

    Java程序多进程运行模式的实例分析 Java程序多进程运行模式是指在Java程序中启动多个Java子进程,每个子进程运行在不同的虚拟机进程中,这样可以提高程序的稳定性,因为如果一个子进程发生异常,不会影响其他子进程...

    Java通过进程名称杀进程

    - JRE是Java应用程序运行时环境的基础部分,包含了Java虚拟机(JVM)、类库以及运行Java程序所需的其他支持组件。 - `Runtime.getRuntime()`方法可以获得当前Java应用程序的`Runtime`实例,从而执行操作系统级别的...

    java实现守护进程,有单独的监听进程, 两个或多个进程,两个或多个jvm

    守护进程通常是一个在后台运行,不与任何终端关联,并且在所有用户会话结束后仍然继续运行的程序。在Unix系统中,我们可以通过特定的方式来创建守护进程,但在Java中,我们可以模拟这种行为。Java中的`java.lang....

    如何使应用程序只运行一个实例(11kb)

    标题中的“如何使应用程序只运行一个实例”是一个常见的软件设计问题,主要涉及到进程管理与并发控制。当一个应用程序被设计成只能单实例运行时,它会阻止用户打开多个相同的应用程序实例,确保所有操作都在同一实例...

    java 进程间利用管道通信实例

    总结来说,这个"java 进程间利用管道通信实例"是一个展示如何在Java中使用管道进行进程间通信的教学项目。通过学习和理解这个例子,开发者可以更好地理解和运用这一基础的IPC技术,为构建多进程系统奠定基础。

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

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

    Java Application-J2SE实例基础程序

    这可以通过`Runtime.getRuntime().exec()`方法实现,允许Java程序启动一个操作系统进程并执行外部命令。例如,可以调用系统自带的计算器或命令行工具。 获取计算机名称和IP地址则涉及到网络编程。Java的`java.net`...

    程序只运行一个实例,并将前一个实例提到前台

    标题中的“程序只运行一个实例,并将前一个实例提到前台”指的是单例模式的应用,这是一种设计模式,确保一个类只有一个实例并且提供一个全局访问点。在计算机程序中,特别是桌面应用软件,这样的设计通常用于保证...

    Java基于socket的进程间通信 聊天小程序

    在这个场景下,我们讨论的是一个简单的聊天小程序,它利用了Java的Socket库来搭建客户端与服务器之间的桥梁,实现数据的实时交互。下面将详细阐述相关知识点。 1. **Java Socket**: Java的Socket类是TCP/IP协议的...

    获取正在运行进程的实例

    进程是操作系统中的一个基本概念,它代表了一个正在执行的程序的实例。每个进程都有自己的内存空间,包括代码段、数据段、堆栈和堆。获取正在运行的进程信息通常是为了进行系统监控、性能分析或者资源管理。 在...

    Java 的多线程,程序、进程和线程的概念31

    当一个程序被运行时,操作系统会为它创建一个进程,每个进程都有独立的内存空间,包含代码、数据、堆栈等资源。 3. **线程**:线程是进程内的一个执行单元,是CPU调度和执行的基本单位。在一个进程中可以有多个线程...

    进程调度程序 Java

    在这个场景中,我们关注的是一个使用Java编程语言实现的进程调度程序。Java作为一种跨平台的高级编程语言,非常适合开发这种系统级的应用。 进程调度的主要目标包括提高系统吞吐量、减少进程等待时间以及保持响应...

    控制只可以运行单个进程

    单进程,顾名思义,是指一个应用程序或服务在任何时候都仅有一个实例在运行。这通常通过实现单例模式来实现,这是一种设计模式,它保证一个类只有一个实例,并提供一个全局访问点。在Windows系统中,可以通过检查...

    商业编程-源码-让多个程序实例运行在同个进程空间的多个线程中.zip

    标题和描述提到的“让多个程序实例运行在同个进程空间的多个线程中”是指在单个进程内创建并管理多个线程来执行不同的任务。这种方式能够充分利用多核处理器的计算能力,提高程序的并发性和响应速度,从而提升整体...

Global site tag (gtag.js) - Google Analytics