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:
- Check if the lock file exists.
- Try to delete the lock file to check if there’s really a running process lock the file.
- Get the file lock.
- If failed to get the lock file, show error that there’s already an instance running –> the end
- If successfully get the lock then go on with your application want to do.
- 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: java, file lock, shutdownhook, lock, single, one, intance
hi, nice article, why that extra thread for unlocking?
@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.
Thank you very much, the post is very precise and very good results.
@santiago
You’re welcome.
Good to know that my blog can help you.
Yes now I understand
, just ctrl+c-ed javaApp that echoed using shutdown hook. Thanks
Jim,
AWESOME solution, it works great!!
Thanks a lot,
Gui
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
Moving to my new domain : http://jimmod.com/blog/?p=60