All Downloads are FREE. Search and download functionalities are using the official Maven repository.

caustic.common.concurrent.Lock.scala Maven / Gradle / Ivy

There is a newer version: 1.3.1
Show newest version
package caustic.common.concurrent

import java.util.concurrent.locks.StampedLock

/**
 * A Scala wrapper around the Java8 StampedLock. Provides a simple abstraction that hides the
 * semantics of acquiring and releasing shared, exclusive, and optimistic locks. The lock is not
 * reentrant. The StampedLock implementation benchmarks significantly better than standard
 * monitor synchronization and the various lock abstractions in the Java concurrency package.
 *
 * @param underlying Underlying lock.
 */
case class Lock(underlying: StampedLock = new StampedLock) {

  /**
   * Returns the result of the provided code block, after acquiring a shared read lock. Because
   * shared locks can be acquired concurrently, the provided function must be side-effect free.
   *
   * @param block Critical section; side-effect free.
   * @return Result of evaluation.
   */
  def shared[T](block: => T): T = {
    val stamp = this.underlying.readLock()
    try {
      block
    } finally {
      this.underlying.unlockRead(stamp)
    }
  }

  /**
   * Returns the result of the provided code block, after acquiring an exclusive write lock. Because
   * exclusive locks may not be acquired concurrently, the provided function may have side-effects.
   *
   * @param block Critical section.
   * @return Result of evaluation.
   */
  def exclusive[T](block: => T): T = {
    val stamp = this.underlying.writeLock()
    try {
      block
    } finally {
      this.underlying.unlockWrite(stamp)
    }
  }

  /**
   * Returns the result of the provided code block, without acquiring a lock. If an exclusive lock
   * was acquired during execution, then the code block is reevaluated under a shared lock. Because
   * the block may be executed multiple times, the provided function must be side-effect free.
   *
   * @param block Critical section; side-effect free.
   * @return Result of evaluation.
   */
  def optimistic[T](block: => T): T = {
    val stamp = this.underlying.tryOptimisticRead()
    val value = block
    if (!this.underlying.validate(stamp)) shared(block) else value
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy