A wrapper around Java's ReentrantReadWriteLock with graceful wait and cleaner fail support.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
src/main/java/com/kolich/bolt
.gitignore
LICENSE
README.md
pom.xml

README.md

kolich-bolt

synonym: lock

A wrapper around Java's ReentrantReadWriteLock with better wait and cleaner fail support.

Wraps a typical ReentrantReadWriteLock with a much cleaner usage pattern. And, lets you define a success callback and have it called upon successful execution of an internal transaction (a critical block that's protected by the lock).

Latest Version

See the Releases page for the latest version.

Resolvers

If you wish to use this artifact, you can easily add it to your existing Maven or Gradle project using my GitHub hosted Maven2 repository.

Maven

<repository>
  <id>Kolichrepo</id>
  <name>Kolich repo</name>
  <url>http://markkolich.github.com/repo/</url>
  <layout>default</layout>
</repository>

<dependency>
  <groupId>com.kolich</groupId>
  <artifactId>kolich-bolt</artifactId>
  <version>0.1</version>
  <scope>compile</scope>
</dependency>

Gradle

compile 'com.kolich:kolich-bolt:0.1'

Usage

Your entity, a class, implements the LockableEntity interface as defined by kolich-bolt.

import com.kolich.bolt.LockableEntity;
import java.util.concurrent.locks.ReadWriteLock;

public final class Foobar implements LockableEntity {
  private final ReadWriteLock lock_;
  public Foobar() {
    lock_ = new ReadWriteLock();
  }
  @Override
  public ReadWriteLock getLock() {
    return lock_;
  }
}

You wish to use an instance of this entity to protect a critical section of code (defined below as a transaction) using a ReentrantReadWriteEntityLock.

public static final Foobar x = new Foobar();

Grab a shared read lock on x, waiting forever on any threads who have already acquired the write lock. If the read lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock has been acquired.

new ReentrantReadWriteEntityLock<T>(x) {
  @Override
  public T transaction() throws Exception {
    // Do something with "x"
    // Return something type T
    return baz;
  }
}.read(); // Wait forever

Grab a shared read lock on x, fail immediately with a LockConflictException if the write lock already acquired by another thread.

new ReentrantReadWriteEntityLock<T>(x) {
  @Override
  public T transaction() throws Exception {
    // Do something with "x"
    // Return something of type T
    return baz;
  }
}.read(false); // Fail immediately if read lock not available

Note that read() asks for a shared reader lock — the lock will be granted if and only if there are no threads holding a write lock on x. There very well may be other reader threads.

Grab an exclusive write lock on x, fail immediately with a LockConflictException if write or read lock already acquired by another thread. Call the success callback method if and only if the transaction method finished cleanly without exception.

new ReentrantReadWriteEntityLock<T>(x) {
  @Override
  public T transaction() throws Exception {
    // Do something with "x"
    // Return something of type T
    return baz;
  }
  @Override
  public T success(final T t) throws Exception {
    // Yay, it worked!
    // Only called if transaction() finished cleanly without exception
    return t;
  }
}.write(); // Fail immediately if write lock not available

NOTE: The acquired lock is held during execution of the success method. It is only released when the success method returns, either in success or failure (throws an exception).

The Havalo project makes extensive real-world use of this locking mechanism.

Building

Clone or fork the repository.

#~> git clone https://github.com/markkolich/kolich-bolt.git

To package the JAR, run mvn package:

mvn package

The resulting JAR is placed into the dist directory.

Licensing

Copyright (c) 2015 Mark S. Kolich

All code in this artifact is freely available for use and redistribution under the MIT License.

See LICENSE for details.