SynchronizedVariable.java

  1. /*
  2.   File: SynchronizedVariable.java

  3.   Originally written by Doug Lea and released into the public domain.
  4.   This may be used for any purposes whatsoever without acknowledgment.
  5.   Thanks for the assistance and support of Sun Microsystems Labs,
  6.   and everyone contributing, testing, and using this code.

  7.   History:
  8.   Date       Who                What
  9.   30Jun1998  dl               Create public version
  10. */

  11. package org.dbunit.util.concurrent;

  12. import org.slf4j.Logger;
  13. import org.slf4j.LoggerFactory;

  14. /**
  15.  * Base class for simple,  small classes
  16.  * maintaining single values that are always accessed
  17.  * and updated under synchronization. Since defining them for only
  18.  * some types seemed too arbitrary, they exist for all basic types,
  19.  * although it is hard to imagine uses for some.
  20.  * <p>
  21.  *   These classes mainly exist so that you do not have to go to the
  22.  *   trouble of writing your own miscellaneous classes and methods
  23.  *   in situations  including:
  24.  *  <ul>
  25.  *   <li> When  you need or want to offload an instance
  26.  *    variable to use its own synchronization lock.
  27.  *    When these objects are used to replace instance variables, they
  28.  *    should almost always be declared as <code>final</code>. This
  29.  *    helps avoid the need to synchronize just to obtain the reference
  30.  *    to the synchronized variable itself.
  31.  *
  32.  *    <li> When you need methods such as set, commit, or swap.
  33.  *    Note however that
  34.  *    the synchronization for these variables is <em>independent</em>
  35.  *    of any other synchronization perfromed using other locks.
  36.  *    So, they are not
  37.  *    normally useful when accesses and updates among
  38.  *    variables must be coordinated.
  39.  *    For example, it would normally be a bad idea to make
  40.  *    a Point class out of two SynchronizedInts, even those
  41.  *    sharing a lock.
  42.  *
  43.  *    <li> When defining <code>static</code> variables. It almost
  44.  *    always works out better to rely on synchronization internal
  45.  *    to these objects, rather  than class locks.
  46.  *  </ul>
  47.  * <p>
  48.  * While they cannot, by nature, share much code,
  49.  * all of these classes work in the same way.
  50.  * <p>
  51.  * <b>Construction</b> <br>
  52.  * Synchronized variables are always constructed holding an
  53.  * initial value of the associated type. Constructors also
  54.  * establish the lock to use for all methods:
  55.  * <ul>
  56.  *   <li> By default, each variable uses itself as the
  57.  *        synchronization lock. This is the most common
  58.  *        choice in the most common usage contexts in which
  59.  *        SynchronizedVariables are used to split off
  60.  *        synchronization locks for independent attributes
  61.  *        of a class.
  62.  *   <li> You can specify any other Object to use as the
  63.  *        synchronization lock. This allows you to
  64.  *        use various forms of `slave synchronization'. For
  65.  *        example, a variable that is always associated with a
  66.  *        particular object can use that object's lock.
  67.  * </ul>
  68.  * <p>
  69.  * <b>Update methods</b><br>
  70.  * Each class supports several kinds of update methods:
  71.  * <ul>
  72.  *   <li> A <code>set</code> method that sets to a new value and returns
  73.  *    previous value. For example, for a SynchronizedBoolean b,
  74.  *    <code>boolean old = b.set(true)</code> performs a test-and-set.
  75.  * <p>
  76.  *   <li> A  <code>commit</code> method that sets to new value only
  77.  *    if currently holding a given value.
  78.  *
  79.  * For example, here is a class that uses an optimistic update
  80.  * loop to recompute a count variable represented as a
  81.  * SynchronizedInt.
  82.  *  <pre>
  83.  *  class X {
  84.  *    private final SynchronizedInt count = new SynchronizedInt(0);
  85.  *
  86.  *    static final int MAX_RETRIES = 1000;
  87.  *
  88.  *    public boolean recomputeCount() throws InterruptedException {
  89.  *      for (int i = 0; i &lt; MAX_RETRIES; ++i) {
  90.  *        int current = count.get();
  91.  *        int next = compute(current);
  92.  *        if (count.commit(current, next))
  93.  *          return true;
  94.  *        else if (Thread.interrupted())
  95.  *          throw new InterruptedException();
  96.  *      }
  97.  *      return false;
  98.  *    }
  99.  *    int compute(int l) { ... some kind of computation ...  }
  100.  *  }
  101.  * </pre>
  102.  * <p>
  103.  *   <li>A <code>swap</code> method that atomically swaps with another
  104.  *    object of the same class using a deadlock-avoidance strategy.
  105.  * <p>
  106.  *    <li> Update-in-place methods appropriate to the type. All
  107.  *    numerical types support:
  108.  *     <ul>
  109.  *       <li> add(x) (equivalent to return value += x)
  110.  *       <li> subtract(x) (equivalent to return value -= x)
  111.  *       <li> multiply(x) (equivalent to return value *= x)
  112.  *       <li> divide(x) (equivalent to return value /= x)
  113.  *     </ul>
  114.  *   Integral types also support:
  115.  *     <ul>
  116.  *       <li> increment() (equivalent to return ++value)
  117.  *       <li> decrement() (equivalent to return --value)
  118.  *     </ul>
  119.  *    Boolean types support:
  120.  *     <ul>
  121.  *       <li> or(x) (equivalent to return value |= x)
  122.  *       <li> and(x) (equivalent to return value &amp;= x)
  123.  *       <li> xor(x) (equivalent to return value ^= x)
  124.  *       <li> complement() (equivalent to return x = !x)
  125.  *     </ul>
  126.  *    These cover most, but not all of the possible operators in Java.
  127.  *    You can add more compute-and-set methods in subclasses. This
  128.  *    is often a good way to avoid the need for ad-hoc synchronized
  129.  *    blocks surrounding expressions.
  130.  *  </ul>
  131.  * <p>
  132.  * <b>Guarded methods</b> <br>
  133.  *   All <code>Waitable</code> subclasses provide notifications on
  134.  *   every value update, and support guarded methods of the form
  135.  *   <code>when</code><em>predicate</em>, that wait until the
  136.  *   predicate hold,  then optionally run any Runnable action
  137.  *   within the lock, and then return. All types support:
  138.  *     <ul>
  139.  *       <li> whenEqual(value, action)
  140.  *       <li> whenNotEqual(value, action)
  141.  *     </ul>
  142.  *   (If the action argument is null, these return immediately
  143.  *   after the predicate holds.)
  144.  *   Numerical types also support
  145.  *     <ul>
  146.  *       <li> whenLess(value, action)
  147.  *       <li> whenLessEqual(value, action)
  148.  *       <li> whenGreater(value, action)
  149.  *       <li> whenGreaterEqual(value, action)
  150.  *     </ul>
  151.  *   The Waitable classes are not always spectacularly efficient since they
  152.  *   provide notifications on all value changes.  They are
  153.  *   designed for use in contexts where either performance is not an
  154.  *   overriding issue, or where nearly every update releases guarded
  155.  *   waits anyway.
  156.  *  <p>
  157.  * <b>Other methods</b> <br>
  158.  *   This class implements Executor, and provides an <code>execute</code>
  159.  *   method that runs the runnable within the lock.
  160.  *   <p>
  161.  *   All classes except SynchronizedRef and WaitableRef implement
  162.  *   <code>Cloneable</code> and <code>Comparable</code>.
  163.  *   Implementations of the corresponding
  164.  *   methods either use default mechanics, or use methods that closely
  165.  *   correspond to their java.lang analogs. SynchronizedRef does not
  166.  *   implement any of these standard interfaces because there are
  167.  *   many cases where it would not make sense. However, you can
  168.  *   easily make simple subclasses that add the appropriate declarations.
  169.  *
  170.  *  <p>
  171.  *
  172.  *
  173.  *
  174.  * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]</p>
  175.  *
  176.  * @author Doug Lea
  177.  * @author Last changed by: $Author$
  178.  * @version $Revision$ $Date$
  179.  * @since ? (pre 2.1)
  180.  */
  181. public class SynchronizedVariable implements Executor {

  182.     /**
  183.      * Logger for this class
  184.      */
  185.     private static final Logger logger = LoggerFactory.getLogger(SynchronizedVariable.class);

  186.   protected final Object lock_;

  187.   /** Create a SynchronizedVariable using the supplied lock **/
  188.   public SynchronizedVariable(Object lock) { lock_ = lock; }

  189.   /** Create a SynchronizedVariable using itself as the lock **/
  190.   public SynchronizedVariable() { lock_ = this; }

  191.   /**
  192.    * Return the lock used for all synchronization for this object
  193.    **/
  194.   public Object getLock() {
  195.     return lock_;
  196.   }

  197.   /**
  198.    * If current thread is not interrupted, execute the given command
  199.    * within this object's lock
  200.    **/

  201.   public void execute(Runnable command) throws InterruptedException {
  202.     logger.debug("execute(command={}) - start", command);
  203.     if (Thread.interrupted()) throw new InterruptedException();
  204.     synchronized (lock_) {
  205.       command.run();
  206.     }
  207.   }
  208. }