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.

Locking may be preferable to synchronization or when an application needs a distinction between read access (multiple threads may have read access concurrently) and write access (only one thread may have write access at any given time).

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