kgiannakakis
kgiannakakis

Reputation: 104198

How to synchronize requests for data with data update process?

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.

Upvotes: 0

Views: 2058

Answers (4)

Javamann
Javamann

Reputation: 2922

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.

Upvotes: 0

Lars A Frøyland
Lars A Frøyland

Reputation: 126

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.

Upvotes: 3

ordnungswidrig
ordnungswidrig

Reputation: 3186

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();
    }

}

Upvotes: 5

Bombe
Bombe

Reputation: 83945

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. */
}

Upvotes: 0

Related Questions