Package org.apache.tapestry5.ioc.internal.util

## Class ConcurrentBarrier

- java.lang.Object
- - org.apache.tapestry5.ioc.internal.util.ConcurrentBarrier

-     public class ConcurrentBarrier
      extends Object

  A barrier used to execute code in a context where it is guarded by read/write locks. In addition, handles upgrading read locks to write locks (and vice versa). Execution of code within a lock is in terms of a `Runnable` object (that returns no value), or a `Invokable` object (which does return a value).

- - ### Constructor Summary

    Constructors
    Constructor | Description
    --- | ---
    `ConcurrentBarrier()` |

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `boolean` | `tryWithWrite​(Runnable runnable, long timeout, TimeUnit timeoutUnit)` | Try to aquire the exclusive write lock and invoke the Runnable.
    `void` | `withRead​(Runnable runnable)` | As with `withRead(Invokable)`, creating an `Invokable` wrapper around the runnable object.
    `<T> T` | `withRead​(Invokable<T> invokable)` | Invokes the object after acquiring the read lock (if necessary).
    `void` | `withWrite​(Runnable runnable)` | As with `withWrite(Invokable)`, creating an `Invokable` wrapper around the runnable object.
    `<T> T` | `withWrite​(Invokable<T> invokable)` | Acquires the exclusive write lock before invoking the Invokable.

    - ### Methods inherited from class java.lang.Object

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

- - ### Constructor Detail

    - #### ConcurrentBarrier

          public ConcurrentBarrier()

  - ### Method Detail

    - #### withRead

          public <T> T withRead​(Invokable<T> invokable)

      Invokes the object after acquiring the read lock (if necessary). If invoked when the read lock has not yet been acquired, then the lock is acquired for the duration of the call. If the lock has already been acquired, then the status of the lock is not changed. TODO: Check to see if the write lock is acquired and not acquire the read lock in that situation. Currently this code is not re-entrant. If a write lock is already acquired and the thread attempts to get the read lock, then the thread will hang. For the moment, all the uses of ConcurrentBarrier are coded in such a way that reentrant locks are not a problem.
      Type Parameters:
        `T` -
      Parameters:
        `invokable` -
      Returns:
        the result of invoking the invokable

    - #### withRead

          public void withRead​(Runnable runnable)

      As with `withRead(Invokable)`, creating an `Invokable` wrapper around the runnable object.

    - #### withWrite

          public <T> T withWrite​(Invokable<T> invokable)

      Acquires the exclusive write lock before invoking the Invokable. The code will be executed exclusively, no other reader or writer threads will exist (they will be blocked waiting for the lock). If the current thread has a read lock, it is released before attempting to acquire the write lock, and re-acquired after the write lock is released. Note that in that short window, between releasing the read lock and acquiring the write lock, it is entirely possible that some other thread will sneak in and do some work, so the `Invokable` object should be prepared for cases where the state has changed slightly, despite holding the read lock. This usually manifests as race conditions where either a) some parallel unrelated bit of work has occured or b) duplicate work has occured. The latter is only problematic if the operation is very expensive.
      Type Parameters:
        `T` -
      Parameters:
        `invokable` -

    - #### withWrite

          public void withWrite​(Runnable runnable)

      As with `withWrite(Invokable)`, creating an `Invokable` wrapper around the runnable object.

    - #### tryWithWrite

          public boolean tryWithWrite​(Runnable runnable,
                                      long timeout,
                                      TimeUnit timeoutUnit)

      Try to aquire the exclusive write lock and invoke the Runnable. If the write lock is obtained within the specfied timeout, then this method behaves as `withWrite(Runnable)` and will return true. If the write lock is not obtained within the timeout then the runnable is never invoked and the method will return false.
      Parameters:
        `runnable` - Runnable object to execute inside the write lock.
        `timeout` - Time to wait for write lock.
        `timeoutUnit` - Units of timeout.
      Returns:
        true if lock was obtained and the runnable executed, or false otherwise.