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