Java tutorial
/* * Copyright (c) 2004 David Flanagan. All rights reserved. * This code is from the book Java Examples in a Nutshell, 3nd Edition. * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied. * You may study, use, and modify it for any non-commercial purpose, * including teaching and use in open-source projects. * You may distribute it non-commercially as long as you retain this notice. * For a commercial use license, or to purchase the book, * please visit http://www.davidflanagan.com/javaexamples3. */ //package je3.nio; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; /** * Lock.java: this class demonstrates file locking and simple file read and * write operations using java.nio.channels.FileChannel. It uses file locking to * prevent two instances of the program from running at the same time. */ public class Lock { public static void main(String args[]) throws IOException, InterruptedException { RandomAccessFile file = null; // The file we'll lock FileChannel f = null; // The channel to the file FileLock lock = null; // The lock object we hold try { // The finally clause closes the channel and releases the lock // We use a temporary file as the lock file. String tmpdir = System.getProperty("java.io.tmpdir"); String filename = Lock.class.getName() + ".lock"; File lockfile = new File(tmpdir, filename); // Create a FileChannel that can read and write that file. // Note that we rely on the java.io package to open the file, // in read/write mode, and then just get a channel from it. // This will create the file if it doesn't exit. We'll arrange // for it to be deleted below, if we succeed in locking it. file = new RandomAccessFile(lockfile, "rw"); f = file.getChannel(); // Try to get an exclusive lock on the file. // This method will return a lock or null, but will not block. // See also FileChannel.lock() for a blocking variant. lock = f.tryLock(); if (lock != null) { // We obtained the lock, so arrange to delete the file when // we're done, and then write the approximate time at which // we'll relinquish the lock into the file. lockfile.deleteOnExit(); // Just a temporary file // First, we need a buffer to hold the timestamp ByteBuffer bytes = ByteBuffer.allocate(8); // a long is 8 bytes // Put the time in the buffer and flip to prepare for writing // Note that many Buffer methods can be "chained" like this. bytes.putLong(System.currentTimeMillis() + 10000).flip(); f.write(bytes); // Write the buffer contents to the channel f.force(false); // Force them out to the disk } else { // We didn't get the lock, which means another instance is // running. First, let the user know this. System.out.println("Another instance is already running"); // Next, we attempt to read the file to figure out how much // longer the other instance will be running. Since we don't // have a lock, the read may fail or return inconsistent data. try { ByteBuffer bytes = ByteBuffer.allocate(8); f.read(bytes); // Read 8 bytes from the file bytes.flip(); // Flip buffer before extracting bytes long exittime = bytes.getLong(); // Read bytes as a long // Figure out how long that time is from now and round // it to the nearest second. long secs = (exittime - System.currentTimeMillis() + 500) / 1000; // And tell the user about it. System.out.println("Try again in about " + secs + " seconds"); } catch (IOException e) { // This probably means that locking is enforced by the OS // and we were prevented from reading the file. } // This is an abnormal exit, so set an exit code. System.exit(1); } // Simulate a real application by sleeping for 10 seconds. System.out.println("Starting..."); Thread.sleep(10000); System.out.println("Exiting."); } finally { // Always release the lock and close the file // Closing the RandomAccessFile also closes its FileChannel. if (lock != null && lock.isValid()) lock.release(); if (file != null) file.close(); } } }