3

I'm looking for a synchronisation method to ensure my back-end data (xml file) is kept intact during multiple client access.

I'm using jaxb to read and write to and from the file. I want to make sure that when a client reads or writes information to the xml file that no other clients are accessing it at the same time.

I've had a read about a ReadWriteLock and wondering if this is the best solution? Obviously clients should run some sort of query to see if anything is currently being writtern to the file, and if not then go ahead with the read/write?

I'm kind of new to java to excuse my ignorance!

Thanks

Shikiryu
  • 10,180
  • 8
  • 49
  • 75
FloweN
  • 89
  • 1
  • 2
  • 8
  • 1
    possible duplicate of [Howto synchronize file access in a shared folder using Java (OR: ReadWriteLock on network level)](http://stackoverflow.com/questions/320159/howto-synchronize-file-access-in-a-shared-folder-using-java-or-readwritelock-on) – dogbane Feb 08 '11 at 12:37
  • Hmm that problem seems alot more complex than mine. In my case its the same application that is reading/writing to the XML file. Everything is done locally as apose to over different virtual machines or networks – FloweN Feb 08 '11 at 13:00

2 Answers2

2

Your problem involves different "clients" - presumably applications running in different JVMs.

If this is the case, the ReadWriteLock class is not going to help. That class is for doing synchronization of different threads within a single JVM.

What you actually want is the FileLock class. This locks a file or region of a file against access by another JVM. You need to do something like this:

    FileInputStream fis = new FileInputStream("someFile");
    FileChannel fc = fis.getChannel();
    FileLock fl = fc.lock();  // or tryLock(), or etc
    // do stuff
    fl.release();
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • note that using this functionality on a network filesystem can be problematic (this is not a java issue, just a standard file locking issue). – jtahlborn Feb 08 '11 at 14:58
  • Also when implenting the simple example i get the following error: java.nio.channels.NonWritableChannelException – FloweN Feb 08 '11 at 16:27
  • @FloweN - file locking doesn't always work; e.g. on network mounted filesystems. There are other issues too. Refer to the "Platform dependencies" section of the FileLock javadoc, for more info. – Stephen C Feb 08 '11 at 16:46
  • @FloweN - the NonWritableChannelException is explained by the javadoc for FileChannel.lock(). For a channel from a FileInputStream you need a shared lock. See the other `lock` method. – Stephen C Feb 08 '11 at 16:50
1

You can use the ReadWriteLock. Basicly it works like this:

When reading the file use this block of code:

Lock l = readwriteLock.readLock();
l.lock();
try {
    // access the xml
} finally {
    l.unlock();
}

when writing use this:

Lock l = readwriteLock.writeLock();
l.lock();
try {
    // access the xml
} finally {
    l.unlock();
}

Multiple threads can read the file at the same time. Only one thread can write at the same time. Whenever you call l.lock() on a read lock, it checks if the writelock is currently locked. If it is, it waits for the unlock() on the writelock.

Whenever you call l.lock() on a write lock, it checks if there are one (or more) currently locked readlocks. If so, it waits for all locks to be unlocked.

This way you can never write when another thread is reading. And you can never read when another thread is writing (but reading from multiple threads at the same time is working).

The-MeLLeR
  • 325
  • 1
  • 8