/native-named-mutex

Cross platform named mutex which provide a system-wide mutex synchronization primitive

Primary LanguageJavaMIT LicenseMIT

Build Status Maven Package Version

native-named-mutex

This is a Java library to provide a cross-platform system-wide named mutex synchronization primitive. It could be used for inter-process synchronization.

Moved to https://github.com/hcoona/one/tree/master/native-named-mutex

<dependency>
    <groupId>io.github.hcoona</groupId>
    <artifactId>native-named-mutex</artifactId>
    <version>1.3.0</version>
</dependency>

Underlying

It underlying use system API to implement Mutex.

Windows

Use CreateMutex API to create or open a named mutex object.

Linux

Use named semaphore in pthread to simulate a mutex.

Other

Use Java FileLock and ReentrantLock to simulate a mutex.

Future plan

Notice that macOS is supported in Other platform because macOS does not implement all posix semaphores API, especially sem_timedwait.

It is possible to leverage the Posix robust mutex with shared memory for more reliability in the future, so please NOT assume it always use semaphore on Linux. (See discussion here for more details)

Usage

Singleton your service in system-wide

You somehow might have to ensure there is only 1 instance running in your system. This is specially useful in enterprise services.

public static void main(String[] args) {
    final String mutexName = "/UniqueNameForYourService";
    try (NamedMutex mutex = NamedMutex.newInstance(true, mutexName)) {
        mutex.waitOne();
        Service service = createYourService();
        service.run();
    }
}

Wait with a timeout limit is also supported.

public static void main(String[] args) {
    final String mutexName = "/UniqueNameForYourService";
    try (NamedMutex mutex = NamedMutex.newInstance(true, mutexName)) {
        if (mutex.waitOne(5, TimeUnit.SECONDS)) {
            Service service = createYourService();
            service.run();
        } else {
            System.err.println("Cannot startup because there is another instance already running.");
        }
    }
}

Protect system-wide resources

You might need to run 2 apps but they have to use same TCP port some time.

try (NamedMutex mutex = NamedMutex.newInstance(true, "/Port_3386")) {
    mutex.waitOne();
    HttpListener listener = new HttpListener("0.0.0.0", 3386);
}

Synchronization between processes

You might need to synchronize between processes.

try (NamedMutex mutex = NamedMutex.newInstance(false, "/ProtectedSharedFileName")) {
    mutex.waitOne();
    writeSharedFile();
}