How to lock a file
===

I have a `write` method that is supposed to safely write data to a file.

    // The current file I am writing to.
    FileOutputStream file = null;
    ...
    // Synchronized version.
    private void write(byte[] bytes) {
      if (file != null && file.getChannel() != null) {
        try {
          boolean written = false;
          do {
            try {
              // Lock it!
              FileLock lock = file.getChannel().lock();
              try {
                // Write the bytes.
                file.write(bytes);
                written = true;
              } finally {
                // Release the lock.
                lock.release();
              }
    
            } catch (OverlappingFileLockException ofle) {
              try {
                // Wait a bit
                Thread.sleep(0);
              } catch (InterruptedException ex) {
                throw new InterruptedIOException("Interrupted waiting for a file lock.");
              }
            }
          } while (!written);
        } catch (IOException ex) {
          log.warn("Failed to lock " + fileName, ex);
        }
      } else {
        log.warn("Failing - " + (file == null ? "file" : "channel") + " is null!!");
      }
    }
    
It has worked fine for me for a while now, although I know there are some wrinkles in it.

I have recently changed a project that uses this code to build and run under Java 5 (from Java 6) and now it looks like it is deadlocked awaiting a lock on the file. It is a multithreaded app and it is quite possible for several threads to attempt to write to the same file. To manage that I hold a synchronized `Map<String,FileOutputStream>` of the open files so all threads are accessing the same file and should therefore correctly bottleneck on this method. 

The debugger tells me that the hung threads are waiting for the `FileLock lock = file.getChannel().lock()` call to return.

Some research brought up this interesting little [nugget](http://docs.oracle.com/javase/1.5.0/docs/api/java/nio/channels/FileChannel.html#lock%28long,%20long,%20boolean%29) which mentions:

> 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 am I doing it wrong? If so what is the right way? If I am doing it right how come I hit a deadlock?