views:

123

answers:

4

I have an application that uses a cron like job to update a set of data. The update process happens once a minute and doesn't last long. A servlet exposes this data set to the users. My problem is that during the update process, the servlet requests should block and wait for the process to complete.

In bottom line I have these two functions:

private void updateData() {    
}

public List getData() {
}

The first function runs once a minute. The second one can be called any number of times simultaneously. When updateData runs, all calls of getData must wait for it to complete. One getData call shouldn't block subsequent calls of the same function. The updateData function has higher priority than the getData, i.e. when updateData is to run, it has to wait for all calls of getData to complete, but new calls shouldn't be allowed to start.

What synchronization mechanism should I use for a case like this? I am using a Java server, but I would be interested to know what solutions exist for other platforms as well.

A: 

You need to synchronize access on the data.

public void updateData() {
    synchronized (updateLock) {
        /* do stuff. */
    }
}


public List getData() {
    List data;
    synchronized (updateLock) {
        data = getRealData();
    }
    /* process/return data. */
}
Bombe
This won't work for me, because I need to be able to call getData simultaneously any number of times. The way you have it, the server can only serve one user at a time.
kgiannakakis
You can call getData() concurrently as often as you want. Access to the data needs to be synchronized, though, otherwise you might end up with inconsistencies. The rest of getData() is free to be run with as many threads as you want.
Bombe
+4  A: 

You can use a ReadWriteLock instead of synchronize.

A ReadWriteLock maintains a pair of associated locks, one for read-only operations and one for writing. The read lock may be held simultaneously by multiple reader threads, so long as there are no writers. The write lock is exclusive.

public void updateData() {
    lock.writeLock().lock();
    try {
        /* do stuff. */
    } finally {
       lock.writeLock().unlock();
    }
}


public List getData() {
    lock.readLock().lock();
    try {
       /* process/return data. */
    } finally {
       lock.readLock().unlock();
    }

}

ordnungswidrig
+2  A: 

Take a look at this article: Read / Write Locks in Java

The only drawback I can see in this example is the notifyAll() waking all waiting threads. It does, however, give priority to write lock requests.

Lars A Frøyland
that's a useful article but it deserves a WARNING, namely that the Java standard distribution already includes a read/write lock (see ordnungswidrig's post)... reinventing the wheel can be dangerous.
Jason S
A: 

CopyOnWriteArrayList or CopyOnWriteArraySet are something good to look at. I've been using them a great deal in situations where the updates are not frequent.

Javamann