Tuesday Apr 22, 2008

Using a FileChannel to force a single process per application

If you haven't played with the FileChannel in the NIO package, you might want to read about it to enforce a single instance of the running process. Using FileChannel you can obtain an exclusive lock on it. Once a process with singleton instance obtains a lock on the FileChannel, it can store this information into the shared (read static) resource and stop one from re-runing another instance of the process.  


{code}


public class LockManager {


    //A map between the filenames and lock files.
    private static Map<String,FileLock> exclusiveLock = new HashMap<String,FileLock>();


    //Lock to protect the threadsafe access.
    private static ReentrantLock lock = new ReentrantLock();


  /\*
     \*Acquires an exclusive lock on the specified file.
     \*/
    public static boolean acquireExclusiveLock(String fileName)
    {
        lock.lock();
        RandomAccessFile raf = null;
        FileChannel channel = null;
        try
        {
            if(exclusiveLock.containsKey(fileName))
            {
                return false;
            }
                   //No lock found. create it.
            File f = new File(fileName);
            if(f.exists()            )
            {
                f.createNewFile();
            }


            //Open the file and get the channel.
            raf = new RandomAccessFile(fileName,"rw";)   ;
            channel = raf.getChannel();


            //Try to obtain an exclusive lock over FileChannel.
            FileLock fileLock = channel.tryLock();
            if(fileLock == null)
            {
                //Couldn't get the lock. Throw the exception to get the resource freed.
                throw new Exception();
            }
            //Put it in the Map.
            exclusiveLock.put(fileName,fileLock);
        }
        catch(Exception e) // Bad to catch all but okay to keep this code short.      


       {
            try
            {
                if(channel!=null)
                {
                    channel.close();
                }
                if(raf!=null)
                {
                    raf.close();
                }
            }
            catch(Exception e1)
            {
                e1.printStackTrace();
            }
            e.printStackTrace();
            return false;
        }
       finally {
            lock.unlock();
        }
        return true;
    }


    /\*
     \*Releases the Lock.
     \*/
    public static boolean releaseLock(String lockFile)
    {
        lock.lock();
        try


           FileLock lock = exclusiveLock.remove(lockFile);
            if(lock!=null)
            {
                lock.release();
            }
            lock.channel().close();
        }
        catch(Exception e)
        {
            e.printStackTrace();
            return false;
        }
        finally {
            lock.unlock();
        }
        return true;
    }

}


 


In the process which should have only one instance:


public class myserver {


          //use a singleton instance


         public static myserver server = new myserver();


         private static boolean serverLocked = false


         private  String fileName;


         public void start()


         {


                 //Get the lock file name, say it's "abc".


                fileName == System.getProperty("user.dir";) + File.pathSeparator + "abc";


                //If not locked, lock it and move forward.


                   if(!LockManager.acquireExclusiveLock(lockFile))
               {
                    //No point of going further.
                    throw new Exception();
               }
               serverLocked = true;
         }


           public void shutdown()


         {


            //Release the lock.


             if(fileName!=null && serverLocked)


             LockManager.releaseLock(fileName);


             ....


          }


{code}


This technique could be used in any application which shouldn't have more than 1 instances running for any reasons.

About

This is the blog of a software engineer, specialized in identity management. Kunal Sinha works in Directory Services Engineering (OpenDS) team from Austin,Texas.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today
Bookmarks