You are here: Advanced Features > Concurrency and db4o > Sharing an Object Container Across Threads > Read Write Lock Example

Read Write Lock Example

This example is the same as used in the shared container topic. Except that it is using read and write locks.

We replace the lock object with a read write lock:

private final ReadWriteLock dataLock = new ReentrantReadWriteLock();
ReadWriteLockingOperations.java: Read write lock

And then on reading operations you use the read lock:

private void listAllPeople(ObjectContainer container) {
    dataLock.readLock().lock();
    try{
        for (Person person : container.query(Person.class)) {
            System.out.println(person.getName());
        }

    } finally{
        dataLock.readLock().unlock();
    }
}
ReadWriteLockingOperations.java: Grab the read-lock to show the data

On insert and update operations you grab the write lock. Note that you need the write lock every time you change some data.

private void updateSomePeople(ObjectContainer container) {
    dataLock.writeLock().lock();
    try {
        final ObjectSet<Person> people = container.query(new Predicate<Person>() {
            @Override
            public boolean match(Person person) {
                return person.getName().equals("Joe");
            }
        });
        for (Person joe : people) {
            joe.setName("New Joe");
            container.store(joe);
        }
    } finally {
        dataLock.writeLock().unlock();
    }
}
ReadWriteLockingOperations.java: Grab the write-lock to change the data

Read Write Lock Transactions

You can use read write locks also in a transaction abstraction. This example is an extension of transaction abstraction example but with read write locks.

First we introduce the read write lock.

private final ReadWriteLock dataLock = new ReentrantReadWriteLock();
DatabaseSupportWithReadWriteLock.java: Read write lock

Then we implement read and write transaction methods:

public <T> T inReadTransaction(TransactionFunction<T> transactionClosure) {
    return inTransaction(dataLock.readLock(),transactionClosure);
}
DatabaseSupportWithReadWriteLock.java: The read transaction method
public <T> T inWriteTransaction(TransactionFunction<T> transactionClosure) {
    return inTransaction(dataLock.writeLock(),transactionClosure);
}
DatabaseSupportWithReadWriteLock.java: The write transaction method
private <T> T inTransaction(Lock lockToGrab,TransactionFunction<T> transactionClosure) {
    lockToGrab.lock();
    try {
        return transactionClosure.inTransaction(database);
    } catch (Exception e) {
        database.rollback();
        throw new TransactionFailedException(e.getMessage(), e);
    } finally {
        database.commit();
        lockToGrab.unlock();
    }
}
DatabaseSupportWithReadWriteLock.java: The transaction implementation

After that we can use these operations in our code:

private void listAllPeople(DatabaseSupportWithReadWriteLock dbSupport) {
    dbSupport.inReadTransaction(new TransactionAction() {
        @Override
        public void inTransaction(ObjectContainer container) {
            final ObjectSet<Person> result = container.query(Person.class);
            for (Person person : result) {
                System.out.println(person.getName());
            }
        }
    });
}
ReadWriteTransactionOperations.java: Use a read transaction for reading objects
private void updateAllJoes(DatabaseSupportWithReadWriteLock dbSupport) {
    dbSupport.inWriteTransaction(new TransactionAction() {
        @Override
        public void inTransaction(ObjectContainer container) {
            final ObjectSet<Person> allJoes = container.query(new Predicate<Person>() {
                @Override
                public boolean match(Person person) {
                    return person.getName().equals("Joe");
                }
            });
            for (Person joe : allJoes) {
                joe.setName("New Joe");
                container.store(joe);
            }
        }
    });
}
ReadWriteTransactionOperations.java: Use a write transaction to update objects