用过金山词霸的人可能都会发现,当你把金山词霸打开,如果再去双击金山词霸 的快捷方式来启动它的时候,系统没有为我们再启动一个新的进程而是激活了前面我们已经打开的金山词霸程序,也就是说我们在一台计算机上同一时刻只能运行一 个金山词霸的实例。这样的软件现在也很多,典型的还有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
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;([B
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'
分享到:
相关推荐
Java程序多进程运行模式的实例分析,实现进程管理。
本人写了一个java进程通信的工具jar,方便大家简单的使用java进程通信。 开启守护进程,获取消息: package com.test; import org.msun.process.ProcessMonitor; import org.msun.process.ProcessMonitor....
Java程序多进程运行模式的实例分析.pdf
java源码包实例源码JAVA开发源码50个合集: Ajax框架 ZK.rar Java图书馆管理系统源程序.rar Java图片倒影效果实例源码.rar Java图片翻折,将图像压扁.rar Java坦克大战网络对战版源代码.rar Java声音播放程序源代码....
Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...
Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...
因为控制台程序出现过因为连接第三方服务超时直接挂掉(此时负载少了一个节点)以及服务器出现意外重启问题(该服务器所有节点宕机),所以需要一个进程守护程序。 也找过 现场的脚本、python的程序、pm2守护方式,...
每运行一个java程序会产生一个java进程,每个java进程可能包含一个或者多个线程,每一个Java进程对应唯一一个JVM实例,每一个JVM实例唯一对应一个堆,每一个线程有一个自己私有的栈。进程所创建的所有类的实例(也...
实例1 开发第一个Java程序 7 第2章 Java基础类型与运算符 实例2 自动提升 9 实例3 自动转换 10 实例4 常用基础类型之强制转换 11 2.2 运算符 12 实例5 算术运算符 12 实例6 关系运算符 13 实例7 逻辑...
实例1 开发第一个Java程序 7 第2章 Java基础类型与运算符(教学视频:39分钟) 9 2.1 基础类型 9 实例2 自动提升 9 实例3 自动转换 10 实例4 常用基础类型之强制转换 11 2.2 运算符 12 实例5 算术运算符 12 实例6 ...
实例1 开发第一个Java程序 7 第2章 Java基础类型与运算符(教学视频:39分钟) 9 2.1 基础类型 9 实例2 自动提升 9 实例3 自动转换 10 实例4 常用基础类型之强制转换 11 2.2 运算符 12 实例5...
HelloWorldApp.java 第一个用Java开发的应用程序。 firstApplet.java 第一个用Java开发的Applet小程序。 firstApplet.htm 用来装载Applet的网页文件 第2章 示例描述:本章介绍开发Java的基础语法知识。 ...
系统运行一个程序即是一个进程从创建,运行到消亡的过程,也就是程序的一次执行过程。简单来说,一个进程就是一个计算机中运行的程序的实例。 线程: 线程是操作系统中的最小执行单元,负责当前进程中程序的执行...
在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程...
在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程...
在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程...
实例1 开发第一个Java程序 7 第2章 Java基础类型与运算符(教学视频:39分钟) 9 2.1 基础类型 9 实例2 自动提升 9 实例3 自动转换 10 实例4 常用基础类型之强制转换 11 2.2 运算符 12 ...
在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程...