John_Woo said:
Thanks lots Steve.
Let's talk about the second aproach further.
I know using:
f = new File("new file");
f.close();
to create a phycical file. but questions :
1. how to obtain an exclusive lock on it? from file API, I can only
see
setReadOnly()
2. if this app is terminated by unexpected way <like in unix, kill
-pid>, how to rm this file?
I do something like this:
File homeDir = new File(System.getProperty("user.home"));
File f = new File(homeDir, "lockFileName");
f.createNewFile();
That creates the file, if it's not present, in the user's home
directory. But it doesn't care if the file's already present. (I'm
omitting try/catch blocks for brevity.)
Then I create a java.io.FileOutputStream around that file:
FileOutputStream fos = new FileOutputStream(f);
The file locking mechanism I use was added in Java 1.4. It's a
java.nio.channels.FileLock. You obtain one like this:
FileLock lock = fos.getChannel().tryLock();
If that succeeds, you've got a non-null FileLock object and an exclusive
lock on the output file. For good measure, I write a single byte to the
file. And I have to keep the FileOutputStream reference as long as my
application is running.
To get the JVM to delete the file automatically, I call:
f.deleteOnExit();
When my app is ready to terminate normally, I close the FileOutputStream
reference I've kept. If I don't, then the deleteOnExit() call has no
effect. If I do close it, then that file goes away automagically.
If your app terminates abnormally -- or you forget to close the output
stream -- then the file will already be there next time around, but that
wouldn't break this approach. The lock attempt will work fine again.
However, if a second instance of your app runs it'll be able to get the
file, but the tryLock() call will result in a null FileLock object when
it cannot lock the file. So the response would be to inform the user
that multiple instances aren't allowed and force a JVM shutdown.
= Steve =