views:

482

answers:

4

Good day,

I need to create a File System Manager (more or less) which can read or write data to files.

My problem is how do I handle concurrency?

I can do something like

public class FileSystemManager {

    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    public byte[] read(String path) {
        readWriteLock.readLock().lock();
        try {
            ...
        } finally {
            readWriteLock.readLock().unlock();
        }
    }
    public void write(String path, byte[] data) {
        readWriteLock.writeLock().lock();
        try {
            ...
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }
}

But this would mean all access to the write (for example) will be locked, even if the first invocation is targeting /tmp/file1.txt and the second invocation is targeting /tmp/file2.txt.

Any ideas how to go about this?

Thanks, Franz

+2  A: 

I would look deeply into Java 5 and the java.util.concurrent package. I'd also recommend reading Brian Goetz' "Java Concurrency in Practice".

duffymo
+3  A: 

Can't you create a different object for each Path and then use synchronize blocks and synchronize on "this"?

gshauger
Franz See
You could use a singleton/cache to create and store the objects. Create like a working set of paths...have the singletons constructor replace the oldest path with the one requested.
gshauger
+4  A: 

Suggest Message Passing For Concurrency Not Threads

In general, this kind of locking happens beneath the java level. Are you really planning on reading and writing the same files and directories? Implementing directories?

Right now there is lots of unsafe threading code that may start blowing up as threads start really running together on multicore hardware.

My suggestion would be to manage concurrency via message passing. You can roll your own if this is an educational exercise, or use one of zillions of queuing and message systems out there. In this kind of system you have only one reader/writer process, but possibly many clients. You avoid the need for file and thread concurrency management.

One advantage of the message passing paradigm is that it will be much, much easier to create a distributed system for load balancing.

DigitalRoss
Two disadvantages are that you incur the cost of message passing and you end up pushing everything through a single "server" thread which will become a bottleneck.
Stephen C
Don't I already incur that bottleneck? How can this improve my situation?
Franz See
+3  A: 

You can store the ReadWriteLock instances in a map keyed on path, just make sure that you get concurrent access to the map correct (possibly using ConcurrentHashMap).

If you actually care about locking the file using operating system primitives you might try looking into using java.nio.FileChannel. This has support for fine grained locking of file regions among other things. Also check out java.nio.channels.FileLock.

Dean Povey
If I use ConcurrentHashMap to store the path-to-ReadWriteLock's, how will I clear up unused ReadWriteLocks? I tried looking at the ReadWriteLock javadoc but I can't seem to find a sure way to find out if it's unused.
Franz See
Acquire a writelock and then remove it from the map. This will block until threads have released read and write locks.
Dean Povey
Actually more specifically have a clean up thread that checks if there are any entries which are not locked. For each of these try to acquire a write lock (with a short timeout). This will avoid a race condition. Then remove the item from the map and release the lock. If the write lock times out then you know something grabbed it in the mean time. Hope that makes sense.
Dean Povey
But doesn't the javadoc says 'Queries if the write lock is held by any thread. This method is designed for use in monitoring system state, not for synchronization control.' Is it safe to use?
Franz See
Not sure I understand the question. ReadWriteLock is safe for synchronization based on access to a shared resource from multiple threads where you wish to improve concurrency by shared access for reads and exclusive access for writes. Is that what you are after?
Dean Povey
Or do you mean you want to actually lock the underlying files.
Dean Povey