Jun 2, 2015

Synchronize code over multiple JVM instances on the same machine

Several years ago I had to build Java application which can have only one running instance on same computer. This leads me to idea using file lock to block other application instances from running.
Not so long ago I have extended this locking functionality and publish it as artifact absolutely with no reason.

You can use file locking not only to run single application instance, but also to synchronize code blocks in different JVM instances on the same computer. So, let me show you how I made this.

Source code can be found here: https://github.com/jneat/javaplugs Note. That you can add it to your project as maven dependency. Just look into Readme.

Main usage principle is to create object with some unique lock ID and use it to acquire or release locks.
import com.github.jneat.app.CrossLock;
//  .. some code

// This is unique lock identifier
String lockId = "lock-id-example";

CrossLock cLock = new CrossLock(lockId);

//  .. some code again

try {
  // In a case when you can acquire lock this method will return true 
  if (cLock.lock()) {
    // Do your synchronized stuff here
  }
} finally {
  // This call will release lock for other processes
  cLock.release();
  // Alternatively you can release lock and remove locking file
  cLock.clear();
}

Also you can use only static methods for locking
import com.github.jneat.app.CrossLock;
//  .. some code

// This is unique lock identifier
String lockId = "lock-id-example";

//  .. some code again

try {
  // In a case when you can acquire lock this method will return true 
  if (CrossLock.get(lockId).lock()) {
    // Do your synchronized stuff here
  }
} finally {
  // This call will release lock for other processes
  CrossLock.get(lockId).release();
  // Alternatively you can release lock and remove locking file
  CrossLock.get(lockId).clear();
}
You can use multiple locks per application. Just change lock id.
import com.github.jneat.app.CrossLock;
//  .. some code

// This is unique lock identifier
String lockId1 = "lock-id-1";
String lockId2 = "lock-id-2";


CrossLock cLock1 = new CrossLock(lockId1);
CrossLock cLock2 = new CrossLock(lockId2);

// Now we have 2 different locks that can be used separately
And this is the way how to use lock to run only single Java application instance.
import com.github.jneat.app.AppLock;
//  .. some code

if(AppLock.lock("my-app-lock-code")) {
  // Run application instance here
  AppLock.release();
} else {
  // Do something on error
  // Maybe show dialog with some message
}


That is all geeks. Hope this stuff may be useful for you.