retepTools Concurrency Support

retepTools Concurrency Support

The retepTools library provides additional concurrency support to that provided by the java.util.concurrency package of JDK 1.5 or later.

The core component of the concurrency support provided by retepTools is the locking. By utilising a set of annotations, it is possible to mark a method so that the entire body of that method is bound to the scope of that Lock.

For example, we have a bean with a property. The properties value can be read by any number of Threads, but it can be set by only one at a time. In the normal java.util.concurrent.lock way you would write something like this:

import java.util.concurrent.locks.ReadWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class MyBean

{

  private final ReadWriteLock lock = new ReentrantReadWriteLock();

  private int value;

  public int getValue()

  {

    lock.readLock().lock();

    try

    {

      return value;

    }

    finally

    {

      lock.readLock().unlock();

    }

  }

  public void setValue( int newValue )

  {

    lock.writeLock().lock();

    try

    {

      value = newValue;

    }

    finally

    {

      lock.writeLock().unlock();

    }

  }

}

Now imaging doing that on an object with dozens of properties… a lot of boiler plate code which is prone to typing errors. retepTools removes this boiler plate code by using a set of thee annotations: @Lock, @ReadLock and @WriteLock.

All three annotations follow a simple contract:

    * your object must implement a corresponding method for each annotation.

    * the associated method is named as it’s annotation, i.e. @ReadLock expects readLock(), etc.

    * that method must be declared either private or “protected final”.

    * the Lock object returned by those methods must also be final – specifically it must be the same object returned for every invocation of that method on that instance.

For convenience the class uk.org.retep.util.collections.ConcurrencySupport implements this contract for objects using @ReadLock and @WriteLock.

So here’s the above code rewritten to use the annotations:

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReadWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

import net.jcip.annotations.ThreadSafe;

import uk.org.retep.annotations.ReadLock;

import uk.org.retep.annotations.WriteLock;

@ThreadSafe

public class MyBean

{

  private final ReadWriteLock lock = new ReentrantReadWriteLock();

  private int value;

  protected final Lock readLock()

  {

    return lock.readLock();

  }

  protected final Lock writeLock()

  {

    return lock.writeLock();

  }

  @ReadLock

  public int getValue()

  {

      return value;

  }

  @WriteLock

  public void setValue( int newValue )

  {

      value = newValue;

  }

}

Now thats alot cleaner, less error prone and yet easier to see what the business logic is rather than having it obscured by the locking mechanism.

retepTools also provides several concrete base classes to make this even easier. The main one is uk.org.retep.util.concurrent.ReadWriteConcurrencySupport which provides concrete implementations of readLock() and writeLock(). So the above example can be made even simpler by extending ReadWriteConcurrencySupport:

import java.util.concurrent.locks.ReadWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

import net.jcip.annotations.ThreadSafe;

import uk.org.retep.annotations.ReadLock;

import uk.org.retep.annotations.WriteLock;

import uk.org.retep.util.concurrent.ReadWriteConcurrencySupport;

@ThreadSafe

public class MyBean extends ConcurrencySupport

{

  private int value;

  @ReadLock

  public int getValue()

  {

      return value;

  }

  @WriteLock

  public void setValue( int newValue )

  {

      value = newValue;

  }

}

Now thats alot cleaner, less error prone and yet easier to see what the business logic is rather than having it obscured by the locking mechanism.

Footnotes

  1. I originally started to write this article back in February however since retepTools 9.2 a new annotation processor was added which performs additional sanity checks.
  2. Project Coin is currently taking proposals for small changes to the Java Language. One of those proposals was Automatic Resource Management and during the debate about that proposal Lock’s were brought up. Now locks are out of scope for that proposal and there is an additional one which now looks like it’s not going to be accepted. I’ll be writing another article about that one later.

Author: petermount1

Prolific Open Source developer who also works in the online gaming industry during the day. Develops in Java, Go, Python & any other language as necessary. Still develops on retro machines like BBC Micro & Amiga A1200

Leave a comment