您可以使用 ManagementFactory 对象。从这里:-
import sun.management.ConnectorAddressLink;
import sun.jvmstat.monitor.HostIdentifier;
import sun.jvmstat.monitor.Monitor;
import sun.jvmstat.monitor.MonitoredHost;
import sun.jvmstat.monitor.MonitoredVm;
import sun.jvmstat.monitor.MonitoredVmUtil;
import sun.jvmstat.monitor.MonitorException;
import sun.jvmstat.monitor.VmIdentifier;
public static void main(String args[]) {
/* The method ManagementFactory.getRuntimeMXBean() returns an identifier with applcation PID
in the Sun JVM, but each jvm may have you own implementation.
So in anothers jvm, other than Sun, this code may not work., :(
*/
RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
final int runtimePid = Integer.parseInt(rt.getName().substring(0,rt.getName().indexOf("@")));
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
// If exists another instance, show message and terminates the current instance.
// Otherwise starts application.
if (getMonitoredVMs(runtimePid))
{
new MainFrame().setVisible(true);
} else
JOptionPane.showMessageDialog(null,"There is another instance of this application running.");
}
});
}
getMonitoredVMs(int processPid)方法接收当前应用程序 PID 作为参数,并捕获从命令行调用的应用程序名称,例如,应用程序是从 c:\java\app\test.jar 路径启动的,然后是值变量是“c:\java\app\teste.jar”。这样,我们将在下面代码的第 17 行捕获应用程序名称。之后,我们在 JVM 中搜索另一个同名进程,如果找到了,并且应用程序 PID 不同,则表示这是第二个应用程序实例。
private static boolean getMonitoredVMs(int processPid) {
MonitoredHost host;
Set vms;
try {
host = MonitoredHost.getMonitoredHost(new HostIdentifier((String)null));
vms = host.activeVms();
} catch (java.net.URISyntaxException sx) {
throw new InternalError(sx.getMessage());
} catch (MonitorException mx) {
throw new InternalError(mx.getMessage());
}
MonitoredVm mvm = null;
String processName = null;
try{
mvm = host.getMonitoredVm(new VmIdentifier(String.valueOf(processPid)));
processName = MonitoredVmUtil.commandLine(mvm);
processName = processName.substring(processName.lastIndexOf("\\") + 1,processName.length());
mvm.detach();
} catch (Exception ex) {
}
// This line is just to verify the process name. It can be removed.
JOptionPane.showMessageDialog(null,processName);
for (Object vmid: vms) {
if (vmid instanceof Integer) {
int pid = ((Integer) vmid).intValue();
String name = vmid.toString(); // default to pid if name not available
try {
mvm = host.getMonitoredVm(new VmIdentifier(name));
// use the command line as the display name
name = MonitoredVmUtil.commandLine(mvm);
name = name.substring(name.lastIndexOf("\\")+1,name.length());
mvm.detach();
if ((name.equalsIgnoreCase(processName)) && (processPid != pid))
return false;
} catch (Exception x) {
// ignore
}
}
}
return true;
}
还要检查使用 SingleInstanceService 服务
javax.jnlp.SingleInstanceService为应用程序提供了一组方法来将自己注册为单例,并注册侦听器以处理从不同应用程序实例传入的参数。