# 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 `Lock`s 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

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static class`
  `LockingVisitors.LockVisitor<O,L>`
  Wraps a domain object and a lock for access by lambdas.
  `static class`
  `LockingVisitors.ReadWriteLockVisitor<O>`
  Wraps a `ReadWriteLock` and object to protect.
  `static class`
  `LockingVisitors.ReentrantLockVisitor<O>`
  Wraps a `ReentrantLock` and object to protect.
  `static class`
  `LockingVisitors.StampedLockVisitor<O>`
  Wraps a `StampedLock` and object to protect.

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `LockingVisitors()`
  Deprecated.
  TODO Make private in 4.0.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static <O> LockingVisitors.ReadWriteLockVisitor<O>`
  `create(O object, ReadWriteLock readWriteLock)`
  Creates a new instance of `LockingVisitors.ReadWriteLockVisitor` with the given object and lock.
  `static <O> LockingVisitors.ReentrantLockVisitor<O>`
  `create(O object, ReentrantLock reentrantLock)`
  Creates a new instance of `LockingVisitors.ReentrantLockVisitor` with the given object and lock.
  `static <O> LockingVisitors.ReentrantLockVisitor<O>`
  `reentrantLockVisitor(O object)`
  Creates a new instance of `LockingVisitors.ReentrantLockVisitor` with the given object.
  `static <O> LockingVisitors.ReadWriteLockVisitor<O>`
  `reentrantReadWriteLockVisitor(O object)`
  Creates a new instance of `LockingVisitors.ReadWriteLockVisitor` with the given object.
  `static <O> LockingVisitors.StampedLockVisitor<O>`
  `stampedLockVisitor(O object)`
  Creates a new instance of `LockingVisitors.StampedLockVisitor` with the given object.

  ### Methods inherited from class Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Constructor Details

  - ### LockingVisitors

    @Deprecated public LockingVisitors()
    Deprecated.
    TODO Make private in 4.0.
    Make private in 4.0.
    See Also:
      - `LockingVisitors`

- ## Method Details

  - ### create

    public static <O> LockingVisitors.ReadWriteLockVisitor<O> create(O object, ReadWriteLock readWriteLock)
    Creates a new instance of `LockingVisitors.ReadWriteLockVisitor` with the given object and lock.
    Type Parameters:
      `O` - The type of the object to protect.
    Parameters:
      `object` - The object to protect.
      `readWriteLock` - The lock to use.
    Returns:
      A new `LockingVisitors.ReadWriteLockVisitor`.
    Since:
      3.13.0
    See Also:
      - `LockingVisitors`

  - ### create

    public static <O> LockingVisitors.ReentrantLockVisitor<O> create(O object, ReentrantLock reentrantLock)
    Creates a new instance of `LockingVisitors.ReentrantLockVisitor` with the given object and lock.
    Type Parameters:
      `O` - The type of the object to protect.
    Parameters:
      `object` - The object to protect.
      `reentrantLock` - The lock to use.
    Returns:
      A new `LockingVisitors.ReentrantLockVisitor`.
    Since:
      3.18.0
    See Also:
      - `LockingVisitors`

  - ### reentrantLockVisitor

    public static <O> LockingVisitors.ReentrantLockVisitor<O> reentrantLockVisitor(O object)
    Creates a new instance of `LockingVisitors.ReentrantLockVisitor` with the given object.
    Type Parameters:
      `O` - The type of the object to protect.
    Parameters:
      `object` - The object to protect.
    Returns:
      A new `LockingVisitors.ReentrantLockVisitor`.
    Since:
      3.18.0
    See Also:
      - `LockingVisitors`

  - ### reentrantReadWriteLockVisitor

    public static <O> LockingVisitors.ReadWriteLockVisitor<O> reentrantReadWriteLockVisitor(O object)
    Creates a new instance of `LockingVisitors.ReadWriteLockVisitor` with the given object.
    Type Parameters:
      `O` - The type of the object to protect.
    Parameters:
      `object` - The object to protect.
    Returns:
      A new `LockingVisitors.ReadWriteLockVisitor`.
    See Also:
      - `LockingVisitors`

  - ### stampedLockVisitor

    public static <O> LockingVisitors.StampedLockVisitor<O> stampedLockVisitor(O object)
    Creates a new instance of `LockingVisitors.StampedLockVisitor` with the given object.
    Type Parameters:
      `O` - The type of the object to protect.
    Parameters:
      `object` - The object to protect.
    Returns:
      A new `LockingVisitors.StampedLockVisitor`.
    See Also:
      - `LockingVisitors`