问题
I'm re-working a Java executable that may be started multiple times, and I want the process to proceed one at a time. In C# I would do this with a named/system Mutex, but this doesn't seem to be possible in Java. How can I achieve this functionality?
回答1:
You can use exclusive access to a File on the File System to achieve similar behavior. I don't think there is something similar to what you've mentioned.
Examples
- Java Programming [Archive] - open File in exclusive lock
- java.nio.channels.FileLock
回答2:
Each time you start Java executable, you start a new instance of Java Virtual Machine (JVM). They are like a different workstations. That's why there is no such a thing like system mutex in Java.
回答3:
Java is a least common denominator tool that provides functionality that is common to all platforms it runs on, that is if it has been implemented yet.
You could use JNA (A simplified way to access native functionality)
In the past I have used sockets to make sure that a program could not start if one was running.
As indicated elsewhere a File based Semaphore could work, of course a downside to this is if the program crashes then your semaphore has to be manually reset.
回答4:
If your operating system provides these mutexes, perhaps you could do with with a native library? ( http://en.wikipedia.org/wiki/Java_Native_Interface ) Of course, you'll be accessing this resource in a OS-specific way, so you'll lose the portability that pure Java gives you.
回答5:
Seems to me that the situation could be addressed with the Singleton design pattern. When using C in Windows I solve the issue with the use of the MutexCreateGlobal()
call. When using an OOP language (i.e., Java) a modified Singleton design pattern seems to do the trick.
public class Singleton {
// **** members ****
private static Singleton singleInstance = null;
private static Semaphore sem = new Semaphore(1);
public int val = 0;
// **** constructor ****
private Singleton() {
val = 0;
}
// **** get instance of this class ****
public static Singleton getInstance() {
// **** request access ****
try {
sem.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
// **** instantiate this class (if needed) ****
if (singleInstance == null) {
// **** instantiate Singleton ****
singleInstance = new Singleton();
// **** inform user what is going on ****
System.out.println("hashCode: " + singleInstance.hashCode());
}
// **** release access ****
sem.release();
// **** return this class ****
return singleInstance;
}
}
回答6:
Remember that Java runs under a Java Virtual Machine. Like OS-level synchronization mechanisms generally only affect the machine on which it runs, native Java synchronization mechanisms only work within that JVM.
Trying to prevent multiple JVMs from being launched to do something is analogous to trying to prevent an application from being run at the same time on multiple physical machines, and is probably not worth the effort.
来源:https://stackoverflow.com/questions/3194227/getting-exclusive-system-wide-lock-in-java