Jimmy’s Blog

Java Application – Make sure only single/one instance running – with File Lock and ShutdownHook

by jimmy on Jul.21, 2008, under English, Java, Programming

Often we want to make sure that only 1 instance our application running.
Because something terrible could happen when more than 1 instance running (for example the whole server would exploded and that would make you fired ;) )

Nevertheless what the reason, one of the way to make this happen is by creating a lock file as a sign that an instance is currently running.
So you application will have this flow:

  1. Check if the lock file exists.
  2. Try to delete the lock file to check if there’s really a running process lock the file.
  3. Get the file lock.
  4. If failed to get the lock file, show error that there’s already an instance running –> the end
  5. If successfully get the lock then go on with your application want to do.
  6. When application ended/closed release the lock and delete the file lock.

package test.jimmy.filelock;
 
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
 
public class MyApp {
 
private static File f;
private static FileChannel channel;
private static FileLock lock;
 
public static void main(String[] args) {
  try {
    f = new File("RingOnRequest.lock");
    // Check if the lock exist
    if (f.exists()) {
    // if exist try to delete it
    f.delete();
  }
  // Try to get the lock
  channel = new RandomAccessFile(f, "rw").getChannel();
  lock = channel.tryLock();
  if(lock == null)
  {
    // File is lock by other application
    channel.close();
    throw new RuntimeException("Only 1 instance of MyApp can run.");
  }
  // Add shutdown hook to release lock when application shutdown
  ShutdownHook shutdownHook = new ShutdownHook();
  Runtime.getRuntime().addShutdownHook(shutdownHook);
 
  //Your application tasks here..
  System.out.println("Running");
  try {
    Thread.sleep(10000);
  } catch (InterruptedException e) {
    e.printStackTrace();
  } catch(IOException e) {
    throw new RuntimeException("Could not start process.", e);
  }
}
 
public static void unlockFile() {
// release and delete file lock
  try {
    if(lock != null) 
    lock.release();
    channel.close();
    f.delete();
  } catch(IOException e) {
    e.printStackTrace();
  }
}
 
static class ShutdownHook extends Thread {
  public void run() {
    unlockFile();
  }
}
 
}

Technorati Tags: , , , , , ,

Related posts:

  1. Simple Log4J implementation
  2. Java 6 "Mustang"
  3. Java ME (J2ME) JSON Implementation Tutorial/Sample
  4. Java – Adding new Classpath at Runtime
  5. Change junit & run file (main class) working directory at Netbeans 5.5 Web Project

:, , , , , ,

12 Comments for this entry

  • Zeratul

    hi, nice article, why that extra thread for unlocking?

  • jimlife

    @Zeratul
    Thanks.
    The extra thread is used by ShutdownHook.
    If you see on line 33-34, I add a thread to current Runtime as ShutdownHook.

    Therefore when MyApp ended either normally or killed (windows – end task / linux – kill command), the thread run() method will be called and it’ll release the lock file.

  • santiago

    Thank you very much, the post is very precise and very good results.

  • jimlife

    @santiago
    You’re welcome.
    Good to know that my blog can help you.

  • Zeratul

    Yes now I understand :) , just ctrl+c-ed javaApp that echoed using shutdown hook. Thanks

  • Guilherme Costa

    Jim,

    AWESOME solution, it works great!!

    Thanks a lot,
    Gui

  • Sandeep Chauhan

    Hi,

    File locking cannot be implemented on Solaris operating system because its file lock is advisory where as on Window platform its mandatory.

    So the provided solution will not lock file on Solaris/linux platform.

    If you know any workaround then please let me know because this bug is not resolved by Java.

    waiting for reply

    Sandeep

  • Thomas

    Works great. Thank you!

  • Nayanish

    Hi,

    >> File locking cannot be implemented on Solaris operating system because its file lock is advisory where as on Window platform its mandatory.

    Any workaround for this?

    Thanks
    Nayn

  • rnb

    “show error that there’s already an instance running” – how show that “error” in the dialog window?

  • xyz

    A FLAW!!
    what if i copy the application to some other directory and run it? in this case, the application can be run easily. rather use a “UNIQUE” location for the “.lock” file or implement the whole mechanism using sockets.
    use some port “xyz” on the system to check the mechanism.

  • jimmy

    Sorry for not replying your comment fast

    @Nayanish : I’m not really familiar with solaris so I don’t think I can give solution for now.

    @rnb : I assuming you’re creating desktop application with JSE. The concept will be the same, but you need to learn / find tutorial about AWT/Swing.. depends on the one you using.

    @xyz : depends on how you design the locking file folder, the sample was use current folder from where user running it.
    To prevent mistake, you can create example a bash script to running it so it will change to specific folder first.
    Or put the lock file in absolute path.
    Using socket is also a solution, but it will take 1 port for each.. depends on your need, if you need 1000 app with 1000 locking, using port will takes to much port.

Leave a Reply

Anti-Spam Protection by WP-SpamFree

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Visit our friends!

A few highly recommended friends...