Class LockingVisitors

java.lang.Object
org.apache.commons.lang3.concurrent.locks.LockingVisitors

public class LockingVisitors extends Object
Combines the monitor and visitor pattern to work with Locks as an alternative to synchronization.

The read and write methods use the locks supplied by the visitor. A LockingVisitors.ReentrantLockVisitor uses one exclusive lock for both methods. A LockingVisitors.ReadWriteLockVisitor uses the underlying read and write locks, while a LockingVisitors.StampedLockVisitor uses its read and write Lock views. Read operations may run concurrently only when the supplied lock supports shared reads.

For example, to use this class with a ReentrantLock:

  1. In single threaded mode, call reentrantLockVisitor(Object), passing the object to protect. This creates a LockingVisitors.ReentrantLockVisitor
  2. To access the protected object, create a FailableConsumer lambda. The consumer will receive the object as a parameter while the visitor holds the lock. Then call LockingVisitors.LockVisitor.acceptReadLocked(FailableConsumer), or LockingVisitors.LockVisitor.acceptWriteLocked(FailableConsumer), passing the consumer.
  3. Alternatively, to receive a result object, use a FailableFunction lambda. To have the function executed, call LockingVisitors.LockVisitor.applyReadLocked(FailableFunction), or LockingVisitors.LockVisitor.applyWriteLocked(FailableFunction).

Example 1: A thread safe logger class using a LockingVisitors.ReentrantLockVisitor.

  public class SimpleLogger1 {

    private final ReentrantLockVisitor<PrintStream> lock;
    private final PrintStream ps;

    public SimpleLogger(OutputStream out) {
        ps = new PrintStream(out);
        lock = LockingVisitors.reentrantLockVisitor(ps);
    }

    public void log(String message) {
        lock.acceptWriteLocked(ps -> ps.println(message));
    }

    public void log(byte[] buffer) {
        lock.acceptWriteLocked(ps -> { ps.write(buffer); ps.println(); });
    }
}

Example 2: A thread safe logger class using a LockingVisitors.ReadWriteLockVisitor.

  public class SimpleLogger2 {

    private final ReadWriteLockVisitor<PrintStream> lock;
    private final PrintStream ps;

    public SimpleLogger(OutputStream out) {
        ps = new PrintStream(out);
        lock = LockingVisitors.readWriteLockVisitor(ps);
    }

    public void log(String message) {
        lock.acceptWriteLocked(ps -> ps.println(message));
    }

    public void log(byte[] buffer) {
        lock.acceptWriteLocked(ps -> { ps.write(buffer); ps.println(); });
    }
}

Example 3: A thread safe logger class using a StampedLock.

  public class SimpleLogger3 {

    private final StampedLockVisitor<PrintStream> lock;
    private final PrintStream ps;

    public SimpleLogger(OutputStream out) {
        ps = new PrintStream(out);
        lock = LockingVisitors.stampedLockVisitor(ps);
    }

    public void log(String message) {
        lock.acceptWriteLocked(ps -> ps.println(message));
    }

    public void log(byte[] buffer) {
        lock.acceptWriteLocked(ps -> { ps.write(buffer); ps.println(); });
    }
}

Since:
3.11