用过金山词霸的人可能都会发现,当你把金山词霸打开,如果再去双击金山词霸 的快捷方式来启动它的时候,系统没有为我们再启动一个新的进程而是激活了前面我们已经打开的金山词霸程序,也就是说我们在一台计算机上同一时刻只能运行一 个金山词霸的实例。这样的软件现在也很多,典型的还有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中,多进程是指在一个程序中启动多个独立的Java虚拟机(JVM)实例,每个实例都可以独立运行自己的任务。这种方式相比于单进程具有以下优势...
总的来说,让多个应用实例运行在同一个进程空间是一种有效的优化手段,但也带来了复杂性。开发者需要具备扎实的并发编程知识,以及对操作系统和编程语言的深入理解。通过多线程或进程间通信,我们可以构建高效且协同...
本人写了一个java进程通信的工具jar,方便大家简单的使用java进程通信。 开启守护进程,获取消息: package com.test; import org.msun.process.ProcessMonitor; import org.msun.process.ProcessMonitor....
异常处理是Java中一个重要的错误处理机制,通过try-catch-finally结构可以捕获并处理运行时异常。学习者应熟悉不同类型的异常,如检查异常和运行时异常,以及何时使用throws关键字。 在实际开发中,设计模式是解决...
Java程序多进程运行模式的实例分析 Java程序多进程运行模式是指在Java程序中启动多个Java子进程,每个子进程运行在不同的虚拟机进程中,这样可以提高程序的稳定性,因为如果一个子进程发生异常,不会影响其他子进程...
- JRE是Java应用程序运行时环境的基础部分,包含了Java虚拟机(JVM)、类库以及运行Java程序所需的其他支持组件。 - `Runtime.getRuntime()`方法可以获得当前Java应用程序的`Runtime`实例,从而执行操作系统级别的...
守护进程通常是一个在后台运行,不与任何终端关联,并且在所有用户会话结束后仍然继续运行的程序。在Unix系统中,我们可以通过特定的方式来创建守护进程,但在Java中,我们可以模拟这种行为。Java中的`java.lang....
标题中的“如何使应用程序只运行一个实例”是一个常见的软件设计问题,主要涉及到进程管理与并发控制。当一个应用程序被设计成只能单实例运行时,它会阻止用户打开多个相同的应用程序实例,确保所有操作都在同一实例...
总结来说,这个"java 进程间利用管道通信实例"是一个展示如何在Java中使用管道进行进程间通信的教学项目。通过学习和理解这个例子,开发者可以更好地理解和运用这一基础的IPC技术,为构建多进程系统奠定基础。
java源码包实例源码JAVA开发源码50个合集: Ajax框架 ZK.rar Java图书馆管理系统源程序.rar Java图片倒影效果实例源码.rar Java图片翻折,将图像压扁.rar Java坦克大战网络对战版源代码.rar Java声音播放程序源代码....
这可以通过`Runtime.getRuntime().exec()`方法实现,允许Java程序启动一个操作系统进程并执行外部命令。例如,可以调用系统自带的计算器或命令行工具。 获取计算机名称和IP地址则涉及到网络编程。Java的`java.net`...
标题中的“程序只运行一个实例,并将前一个实例提到前台”指的是单例模式的应用,这是一种设计模式,确保一个类只有一个实例并且提供一个全局访问点。在计算机程序中,特别是桌面应用软件,这样的设计通常用于保证...
在这个场景下,我们讨论的是一个简单的聊天小程序,它利用了Java的Socket库来搭建客户端与服务器之间的桥梁,实现数据的实时交互。下面将详细阐述相关知识点。 1. **Java Socket**: Java的Socket类是TCP/IP协议的...
进程是操作系统中的一个基本概念,它代表了一个正在执行的程序的实例。每个进程都有自己的内存空间,包括代码段、数据段、堆栈和堆。获取正在运行的进程信息通常是为了进行系统监控、性能分析或者资源管理。 在...
当一个程序被运行时,操作系统会为它创建一个进程,每个进程都有独立的内存空间,包含代码、数据、堆栈等资源。 3. **线程**:线程是进程内的一个执行单元,是CPU调度和执行的基本单位。在一个进程中可以有多个线程...
在这个场景中,我们关注的是一个使用Java编程语言实现的进程调度程序。Java作为一种跨平台的高级编程语言,非常适合开发这种系统级的应用。 进程调度的主要目标包括提高系统吞吐量、减少进程等待时间以及保持响应...
单进程,顾名思义,是指一个应用程序或服务在任何时候都仅有一个实例在运行。这通常通过实现单例模式来实现,这是一种设计模式,它保证一个类只有一个实例,并提供一个全局访问点。在Windows系统中,可以通过检查...
标题和描述提到的“让多个程序实例运行在同个进程空间的多个线程中”是指在单个进程内创建并管理多个线程来执行不同的任务。这种方式能够充分利用多核处理器的计算能力,提高程序的并发性和响应速度,从而提升整体...