Mercurial > hg > blitz_condensed
comparison src/EDU/oswego/cs/dl/util/concurrent/SynchronizedVariable.java @ 0:3dc0c5604566
Initial checkin of blitz 2.0 fcs - no installer yet.
author | Dan Creswell <dan.creswell@gmail.com> |
---|---|
date | Sat, 21 Mar 2009 11:00:06 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:3dc0c5604566 |
---|---|
1 /* | |
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 } |