Question

Does the following Java code guarantee an exclusive lock on an unopened file in Windows?

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test {
    public static void main(String[] args) {
        File file = new File("mylog.log");
        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.getChannel().lock();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Was it helpful?

Solution

As may be seen in Java specs:

File locks are held on behalf of the entire Java virtual machine. They are not suitable for controlling access to a file by multiple threads within the same virtual machine.

So if you need exclusive lock for the thread, please choose another way.

OTHER TIPS

tl;dr: No. You cannot make assumptions about the behavior of the host operating system's treatment of your locks.

Good news: Are you trying to ensure that you have a thread-safe locking mechanism within your application? If so, FileLock is sufficient (assuming that the rest of the application is composed of properly written thread-safe code, of course).

Bad news: Unfortunately, if you are trying to ensure that Windows will honor your lock over all applications, you cannot count on that.

This is easy to observe in Windows: you can often overwrite files that are being written to (when log files get too long, I have emacs chop all the previous spam, for example). That said, Windows usually will not allow you to delete an open file.

From the FileLock documentation:

File locks are held on behalf of the entire Java virtual machine. They are not suitable for controlling access to a file by multiple threads within the same virtual machine.

File-lock objects are safe for use by multiple concurrent threads.

... and later ...

Whether or not a lock actually prevents another program from accessing the content of the locked region is system-dependent and therefore unspecified. The native file-locking facilities of some systems are merely advisory, meaning that programs must cooperatively observe a known locking protocol in order to guarantee data integrity. On other systems native file locks are mandatory, meaning that if one program locks a region of a file then other programs are actually prevented from accessing that region in a way that would violate the lock. On yet other systems, whether native file locks are advisory or mandatory is configurable on a per-file basis. To ensure consistent and correct behavior across platforms, it is strongly recommended that the locks provided by this API be used as if they were advisory locks.

Even if you use lock and unlock flags for the file, you're only guaranteeing that you have an exclusive lock within your Java application.

You either have to use the JNI, or another computer language, to make the Windows calls to guarantee an exclusive lock on a Windows file.

Windows LockFile function

Windows UnlockFile function

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top